1/* 2 * Specific bus support for PMC-TWI compliant implementation on MSP71xx. 3 * 4 * Copyright 2005-2007 PMC-Sierra, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 * 11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 */ 22 23#include <linux/kernel.h> 24#include <linux/module.h> 25#include <linux/platform_device.h> 26#include <linux/i2c.h> 27#include <linux/interrupt.h> 28#include <linux/completion.h> 29#include <linux/mutex.h> 30#include <linux/delay.h> 31#include <linux/io.h> 32 33#define DRV_NAME "pmcmsptwi" 34 35#define MSP_TWI_SF_CLK_REG_OFFSET 0x00 36#define MSP_TWI_HS_CLK_REG_OFFSET 0x04 37#define MSP_TWI_CFG_REG_OFFSET 0x08 38#define MSP_TWI_CMD_REG_OFFSET 0x0c 39#define MSP_TWI_ADD_REG_OFFSET 0x10 40#define MSP_TWI_DAT_0_REG_OFFSET 0x14 41#define MSP_TWI_DAT_1_REG_OFFSET 0x18 42#define MSP_TWI_INT_STS_REG_OFFSET 0x1c 43#define MSP_TWI_INT_MSK_REG_OFFSET 0x20 44#define MSP_TWI_BUSY_REG_OFFSET 0x24 45 46#define MSP_TWI_INT_STS_DONE (1 << 0) 47#define MSP_TWI_INT_STS_LOST_ARBITRATION (1 << 1) 48#define MSP_TWI_INT_STS_NO_RESPONSE (1 << 2) 49#define MSP_TWI_INT_STS_DATA_COLLISION (1 << 3) 50#define MSP_TWI_INT_STS_BUSY (1 << 4) 51#define MSP_TWI_INT_STS_ALL 0x1f 52 53#define MSP_MAX_BYTES_PER_RW 8 54#define MSP_MAX_POLL 5 55#define MSP_POLL_DELAY 10 56#define MSP_IRQ_TIMEOUT (MSP_MAX_POLL * MSP_POLL_DELAY) 57 58/* IO Operation macros */ 59#define pmcmsptwi_readl __raw_readl 60#define pmcmsptwi_writel __raw_writel 61 62/* TWI command type */ 63enum pmcmsptwi_cmd_type { 64 MSP_TWI_CMD_WRITE = 0, /* Write only */ 65 MSP_TWI_CMD_READ = 1, /* Read only */ 66 MSP_TWI_CMD_WRITE_READ = 2, /* Write then Read */ 67}; 68 69/* The possible results of the xferCmd */ 70enum pmcmsptwi_xfer_result { 71 MSP_TWI_XFER_OK = 0, 72 MSP_TWI_XFER_TIMEOUT, 73 MSP_TWI_XFER_BUSY, 74 MSP_TWI_XFER_DATA_COLLISION, 75 MSP_TWI_XFER_NO_RESPONSE, 76 MSP_TWI_XFER_LOST_ARBITRATION, 77}; 78 79/* Corresponds to a PMCTWI clock configuration register */ 80struct pmcmsptwi_clock { 81 u8 filter; /* Bits 15:12, default = 0x03 */ 82 u16 clock; /* Bits 9:0, default = 0x001f */ 83}; 84 85struct pmcmsptwi_clockcfg { 86 struct pmcmsptwi_clock standard; /* The standard/fast clock config */ 87 struct pmcmsptwi_clock highspeed; /* The highspeed clock config */ 88}; 89 90/* Corresponds to the main TWI configuration register */ 91struct pmcmsptwi_cfg { 92 u8 arbf; /* Bits 15:12, default=0x03 */ 93 u8 nak; /* Bits 11:8, default=0x03 */ 94 u8 add10; /* Bit 7, default=0x00 */ 95 u8 mst_code; /* Bits 6:4, default=0x00 */ 96 u8 arb; /* Bit 1, default=0x01 */ 97 u8 highspeed; /* Bit 0, default=0x00 */ 98}; 99 100/* A single pmctwi command to issue */ 101struct pmcmsptwi_cmd { 102 u16 addr; /* The slave address (7 or 10 bits) */ 103 enum pmcmsptwi_cmd_type type; /* The command type */ 104 u8 write_len; /* Number of bytes in the write buffer */ 105 u8 read_len; /* Number of bytes in the read buffer */ 106 u8 *write_data; /* Buffer of characters to send */ 107 u8 *read_data; /* Buffer to fill with incoming data */ 108}; 109 110/* The private data */ 111struct pmcmsptwi_data { 112 void __iomem *iobase; /* iomapped base for IO */ 113 int irq; /* IRQ to use (0 disables) */ 114 struct completion wait; /* Completion for xfer */ 115 struct mutex lock; /* Used for threadsafeness */ 116 enum pmcmsptwi_xfer_result last_result; /* result of last xfer */ 117}; 118 119/* The default settings */ 120static const struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = { 121 .standard = { 122 .filter = 0x3, 123 .clock = 0x1f, 124 }, 125 .highspeed = { 126 .filter = 0x3, 127 .clock = 0x1f, 128 }, 129}; 130 131static const struct pmcmsptwi_cfg pmcmsptwi_defcfg = { 132 .arbf = 0x03, 133 .nak = 0x03, 134 .add10 = 0x00, 135 .mst_code = 0x00, 136 .arb = 0x01, 137 .highspeed = 0x00, 138}; 139 140static struct pmcmsptwi_data pmcmsptwi_data; 141 142static struct i2c_adapter pmcmsptwi_adapter; 143 144/* inline helper functions */ 145static inline u32 pmcmsptwi_clock_to_reg( 146 const struct pmcmsptwi_clock *clock) 147{ 148 return ((clock->filter & 0xf) << 12) | (clock->clock & 0x03ff); 149} 150 151static inline u32 pmcmsptwi_cfg_to_reg(const struct pmcmsptwi_cfg *cfg) 152{ 153 return ((cfg->arbf & 0xf) << 12) | 154 ((cfg->nak & 0xf) << 8) | 155 ((cfg->add10 & 0x1) << 7) | 156 ((cfg->mst_code & 0x7) << 4) | 157 ((cfg->arb & 0x1) << 1) | 158 (cfg->highspeed & 0x1); 159} 160 161static inline void pmcmsptwi_reg_to_cfg(u32 reg, struct pmcmsptwi_cfg *cfg) 162{ 163 cfg->arbf = (reg >> 12) & 0xf; 164 cfg->nak = (reg >> 8) & 0xf; 165 cfg->add10 = (reg >> 7) & 0x1; 166 cfg->mst_code = (reg >> 4) & 0x7; 167 cfg->arb = (reg >> 1) & 0x1; 168 cfg->highspeed = reg & 0x1; 169} 170 171/* 172 * Sets the current clock configuration 173 */ 174static void pmcmsptwi_set_clock_config(const struct pmcmsptwi_clockcfg *cfg, 175 struct pmcmsptwi_data *data) 176{ 177 mutex_lock(&data->lock); 178 pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->standard), 179 data->iobase + MSP_TWI_SF_CLK_REG_OFFSET); 180 pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->highspeed), 181 data->iobase + MSP_TWI_HS_CLK_REG_OFFSET); 182 mutex_unlock(&data->lock); 183} 184 185/* 186 * Gets the current TWI bus configuration 187 */ 188static void pmcmsptwi_get_twi_config(struct pmcmsptwi_cfg *cfg, 189 struct pmcmsptwi_data *data) 190{ 191 mutex_lock(&data->lock); 192 pmcmsptwi_reg_to_cfg(pmcmsptwi_readl( 193 data->iobase + MSP_TWI_CFG_REG_OFFSET), cfg); 194 mutex_unlock(&data->lock); 195} 196 197/* 198 * Sets the current TWI bus configuration 199 */ 200static void pmcmsptwi_set_twi_config(const struct pmcmsptwi_cfg *cfg, 201 struct pmcmsptwi_data *data) 202{ 203 mutex_lock(&data->lock); 204 pmcmsptwi_writel(pmcmsptwi_cfg_to_reg(cfg), 205 data->iobase + MSP_TWI_CFG_REG_OFFSET); 206 mutex_unlock(&data->lock); 207} 208 209/* 210 * Parses the 'int_sts' register and returns a well-defined error code 211 */ 212static enum pmcmsptwi_xfer_result pmcmsptwi_get_result(u32 reg) 213{ 214 if (reg & MSP_TWI_INT_STS_LOST_ARBITRATION) { 215 dev_dbg(&pmcmsptwi_adapter.dev, 216 "Result: Lost arbitration\n"); 217 return MSP_TWI_XFER_LOST_ARBITRATION; 218 } else if (reg & MSP_TWI_INT_STS_NO_RESPONSE) { 219 dev_dbg(&pmcmsptwi_adapter.dev, 220 "Result: No response\n"); 221 return MSP_TWI_XFER_NO_RESPONSE; 222 } else if (reg & MSP_TWI_INT_STS_DATA_COLLISION) { 223 dev_dbg(&pmcmsptwi_adapter.dev, 224 "Result: Data collision\n"); 225 return MSP_TWI_XFER_DATA_COLLISION; 226 } else if (reg & MSP_TWI_INT_STS_BUSY) { 227 dev_dbg(&pmcmsptwi_adapter.dev, 228 "Result: Bus busy\n"); 229 return MSP_TWI_XFER_BUSY; 230 } 231 232 dev_dbg(&pmcmsptwi_adapter.dev, "Result: Operation succeeded\n"); 233 return MSP_TWI_XFER_OK; 234} 235 236/* 237 * In interrupt mode, handle the interrupt. 238 * NOTE: Assumes data->lock is held. 239 */ 240static irqreturn_t pmcmsptwi_interrupt(int irq, void *ptr) 241{ 242 struct pmcmsptwi_data *data = ptr; 243 244 u32 reason = pmcmsptwi_readl(data->iobase + 245 MSP_TWI_INT_STS_REG_OFFSET); 246 pmcmsptwi_writel(reason, data->iobase + MSP_TWI_INT_STS_REG_OFFSET); 247 248 dev_dbg(&pmcmsptwi_adapter.dev, "Got interrupt 0x%08x\n", reason); 249 if (!(reason & MSP_TWI_INT_STS_DONE)) 250 return IRQ_NONE; 251 252 data->last_result = pmcmsptwi_get_result(reason); 253 complete(&data->wait); 254 255 return IRQ_HANDLED; 256} 257 258/* 259 * Probe for and register the device and return 0 if there is one. 260 */ 261static int pmcmsptwi_probe(struct platform_device *pldev) 262{ 263 struct resource *res; 264 int rc = -ENODEV; 265 266 /* get the static platform resources */ 267 res = platform_get_resource(pldev, IORESOURCE_MEM, 0); 268 if (!res) { 269 dev_err(&pldev->dev, "IOMEM resource not found\n"); 270 goto ret_err; 271 } 272 273 /* reserve the memory region */ 274 if (!request_mem_region(res->start, resource_size(res), 275 pldev->name)) { 276 dev_err(&pldev->dev, 277 "Unable to get memory/io address region %pap\n", 278 &res->start); 279 rc = -EBUSY; 280 goto ret_err; 281 } 282 283 /* remap the memory */ 284 pmcmsptwi_data.iobase = ioremap(res->start, 285 resource_size(res)); 286 if (!pmcmsptwi_data.iobase) { 287 dev_err(&pldev->dev, 288 "Unable to ioremap address %pap\n", &res->start); 289 rc = -EIO; 290 goto ret_unreserve; 291 } 292 293 /* request the irq */ 294 pmcmsptwi_data.irq = platform_get_irq(pldev, 0); 295 if (pmcmsptwi_data.irq) { 296 rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt, 297 IRQF_SHARED, pldev->name, &pmcmsptwi_data); 298 if (rc == 0) { 299 /* 300 * Enable 'DONE' interrupt only. 301 * 302 * If you enable all interrupts, you will get one on 303 * error and another when the operation completes. 304 * This way you only have to handle one interrupt, 305 * but you can still check all result flags. 306 */ 307 pmcmsptwi_writel(MSP_TWI_INT_STS_DONE, 308 pmcmsptwi_data.iobase + 309 MSP_TWI_INT_MSK_REG_OFFSET); 310 } else { 311 dev_warn(&pldev->dev, 312 "Could not assign TWI IRQ handler " 313 "to irq %d (continuing with poll)\n", 314 pmcmsptwi_data.irq); 315 pmcmsptwi_data.irq = 0; 316 } 317 } 318 319 init_completion(&pmcmsptwi_data.wait); 320 mutex_init(&pmcmsptwi_data.lock); 321 322 pmcmsptwi_set_clock_config(&pmcmsptwi_defclockcfg, &pmcmsptwi_data); 323 pmcmsptwi_set_twi_config(&pmcmsptwi_defcfg, &pmcmsptwi_data); 324 325 printk(KERN_INFO DRV_NAME ": Registering MSP71xx I2C adapter\n"); 326 327 pmcmsptwi_adapter.dev.parent = &pldev->dev; 328 platform_set_drvdata(pldev, &pmcmsptwi_adapter); 329 i2c_set_adapdata(&pmcmsptwi_adapter, &pmcmsptwi_data); 330 331 rc = i2c_add_adapter(&pmcmsptwi_adapter); 332 if (rc) 333 goto ret_unmap; 334 335 return 0; 336 337ret_unmap: 338 if (pmcmsptwi_data.irq) { 339 pmcmsptwi_writel(0, 340 pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET); 341 free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data); 342 } 343 344 iounmap(pmcmsptwi_data.iobase); 345 346ret_unreserve: 347 release_mem_region(res->start, resource_size(res)); 348 349ret_err: 350 return rc; 351} 352 353/* 354 * Release the device and return 0 if there is one. 355 */ 356static int pmcmsptwi_remove(struct platform_device *pldev) 357{ 358 struct resource *res; 359 360 i2c_del_adapter(&pmcmsptwi_adapter); 361 362 if (pmcmsptwi_data.irq) { 363 pmcmsptwi_writel(0, 364 pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET); 365 free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data); 366 } 367 368 iounmap(pmcmsptwi_data.iobase); 369 370 res = platform_get_resource(pldev, IORESOURCE_MEM, 0); 371 release_mem_region(res->start, resource_size(res)); 372 373 return 0; 374} 375 376/* 377 * Polls the 'busy' register until the command is complete. 378 * NOTE: Assumes data->lock is held. 379 */ 380static void pmcmsptwi_poll_complete(struct pmcmsptwi_data *data) 381{ 382 int i; 383 384 for (i = 0; i < MSP_MAX_POLL; i++) { 385 u32 val = pmcmsptwi_readl(data->iobase + 386 MSP_TWI_BUSY_REG_OFFSET); 387 if (val == 0) { 388 u32 reason = pmcmsptwi_readl(data->iobase + 389 MSP_TWI_INT_STS_REG_OFFSET); 390 pmcmsptwi_writel(reason, data->iobase + 391 MSP_TWI_INT_STS_REG_OFFSET); 392 data->last_result = pmcmsptwi_get_result(reason); 393 return; 394 } 395 udelay(MSP_POLL_DELAY); 396 } 397 398 dev_dbg(&pmcmsptwi_adapter.dev, "Result: Poll timeout\n"); 399 data->last_result = MSP_TWI_XFER_TIMEOUT; 400} 401 402/* 403 * Do the transfer (low level): 404 * May use interrupt-driven or polling, depending on if an IRQ is 405 * presently registered. 406 * NOTE: Assumes data->lock is held. 407 */ 408static enum pmcmsptwi_xfer_result pmcmsptwi_do_xfer( 409 u32 reg, struct pmcmsptwi_data *data) 410{ 411 dev_dbg(&pmcmsptwi_adapter.dev, "Writing cmd reg 0x%08x\n", reg); 412 pmcmsptwi_writel(reg, data->iobase + MSP_TWI_CMD_REG_OFFSET); 413 if (data->irq) { 414 unsigned long timeleft = wait_for_completion_timeout( 415 &data->wait, MSP_IRQ_TIMEOUT); 416 if (timeleft == 0) { 417 dev_dbg(&pmcmsptwi_adapter.dev, 418 "Result: IRQ timeout\n"); 419 complete(&data->wait); 420 data->last_result = MSP_TWI_XFER_TIMEOUT; 421 } 422 } else 423 pmcmsptwi_poll_complete(data); 424 425 return data->last_result; 426} 427 428/* 429 * Helper routine, converts 'pmctwi_cmd' struct to register format 430 */ 431static inline u32 pmcmsptwi_cmd_to_reg(const struct pmcmsptwi_cmd *cmd) 432{ 433 return ((cmd->type & 0x3) << 8) | 434 (((cmd->write_len - 1) & 0x7) << 4) | 435 ((cmd->read_len - 1) & 0x7); 436} 437 438/* 439 * Do the transfer (high level) 440 */ 441static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd( 442 struct pmcmsptwi_cmd *cmd, 443 struct pmcmsptwi_data *data) 444{ 445 enum pmcmsptwi_xfer_result retval; 446 447 mutex_lock(&data->lock); 448 dev_dbg(&pmcmsptwi_adapter.dev, 449 "Setting address to 0x%04x\n", cmd->addr); 450 pmcmsptwi_writel(cmd->addr, data->iobase + MSP_TWI_ADD_REG_OFFSET); 451 452 if (cmd->type == MSP_TWI_CMD_WRITE || 453 cmd->type == MSP_TWI_CMD_WRITE_READ) { 454 u64 tmp = be64_to_cpup((__be64 *)cmd->write_data); 455 tmp >>= (MSP_MAX_BYTES_PER_RW - cmd->write_len) * 8; 456 dev_dbg(&pmcmsptwi_adapter.dev, "Writing 0x%016llx\n", tmp); 457 pmcmsptwi_writel(tmp & 0x00000000ffffffffLL, 458 data->iobase + MSP_TWI_DAT_0_REG_OFFSET); 459 if (cmd->write_len > 4) 460 pmcmsptwi_writel(tmp >> 32, 461 data->iobase + MSP_TWI_DAT_1_REG_OFFSET); 462 } 463 464 retval = pmcmsptwi_do_xfer(pmcmsptwi_cmd_to_reg(cmd), data); 465 if (retval != MSP_TWI_XFER_OK) 466 goto xfer_err; 467 468 if (cmd->type == MSP_TWI_CMD_READ || 469 cmd->type == MSP_TWI_CMD_WRITE_READ) { 470 int i; 471 u64 rmsk = ~(0xffffffffffffffffLL << (cmd->read_len * 8)); 472 u64 tmp = (u64)pmcmsptwi_readl(data->iobase + 473 MSP_TWI_DAT_0_REG_OFFSET); 474 if (cmd->read_len > 4) 475 tmp |= (u64)pmcmsptwi_readl(data->iobase + 476 MSP_TWI_DAT_1_REG_OFFSET) << 32; 477 tmp &= rmsk; 478 dev_dbg(&pmcmsptwi_adapter.dev, "Read 0x%016llx\n", tmp); 479 480 for (i = 0; i < cmd->read_len; i++) 481 cmd->read_data[i] = tmp >> i; 482 } 483 484xfer_err: 485 mutex_unlock(&data->lock); 486 487 return retval; 488} 489 490/* -- Algorithm functions -- */ 491 492/* 493 * Sends an i2c command out on the adapter 494 */ 495static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, 496 struct i2c_msg *msg, int num) 497{ 498 struct pmcmsptwi_data *data = i2c_get_adapdata(adap); 499 struct pmcmsptwi_cmd cmd; 500 struct pmcmsptwi_cfg oldcfg, newcfg; 501 int ret; 502 503 if (num == 2) { 504 struct i2c_msg *nextmsg = msg + 1; 505 506 cmd.type = MSP_TWI_CMD_WRITE_READ; 507 cmd.write_len = msg->len; 508 cmd.write_data = msg->buf; 509 cmd.read_len = nextmsg->len; 510 cmd.read_data = nextmsg->buf; 511 } else if (msg->flags & I2C_M_RD) { 512 cmd.type = MSP_TWI_CMD_READ; 513 cmd.read_len = msg->len; 514 cmd.read_data = msg->buf; 515 cmd.write_len = 0; 516 cmd.write_data = NULL; 517 } else { 518 cmd.type = MSP_TWI_CMD_WRITE; 519 cmd.read_len = 0; 520 cmd.read_data = NULL; 521 cmd.write_len = msg->len; 522 cmd.write_data = msg->buf; 523 } 524 525 cmd.addr = msg->addr; 526 527 if (msg->flags & I2C_M_TEN) { 528 pmcmsptwi_get_twi_config(&newcfg, data); 529 memcpy(&oldcfg, &newcfg, sizeof(oldcfg)); 530 531 /* Set the special 10-bit address flag */ 532 newcfg.add10 = 1; 533 534 pmcmsptwi_set_twi_config(&newcfg, data); 535 } 536 537 /* Execute the command */ 538 ret = pmcmsptwi_xfer_cmd(&cmd, data); 539 540 if (msg->flags & I2C_M_TEN) 541 pmcmsptwi_set_twi_config(&oldcfg, data); 542 543 dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n", 544 (msg->flags & I2C_M_RD) ? "read" : "write", msg->len, 545 (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed"); 546 547 if (ret != MSP_TWI_XFER_OK) { 548 /* 549 * TODO: We could potentially loop and retry in the case 550 * of MSP_TWI_XFER_TIMEOUT. 551 */ 552 return -EIO; 553 } 554 555 return num; 556} 557 558static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter) 559{ 560 return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | 561 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | 562 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL; 563} 564 565static const struct i2c_adapter_quirks pmcmsptwi_i2c_quirks = { 566 .flags = I2C_AQ_COMB_WRITE_THEN_READ | I2C_AQ_NO_ZERO_LEN, 567 .max_write_len = MSP_MAX_BYTES_PER_RW, 568 .max_read_len = MSP_MAX_BYTES_PER_RW, 569 .max_comb_1st_msg_len = MSP_MAX_BYTES_PER_RW, 570 .max_comb_2nd_msg_len = MSP_MAX_BYTES_PER_RW, 571}; 572 573/* -- Initialization -- */ 574 575static const struct i2c_algorithm pmcmsptwi_algo = { 576 .master_xfer = pmcmsptwi_master_xfer, 577 .functionality = pmcmsptwi_i2c_func, 578}; 579 580static struct i2c_adapter pmcmsptwi_adapter = { 581 .owner = THIS_MODULE, 582 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 583 .algo = &pmcmsptwi_algo, 584 .quirks = &pmcmsptwi_i2c_quirks, 585 .name = DRV_NAME, 586}; 587 588static struct platform_driver pmcmsptwi_driver = { 589 .probe = pmcmsptwi_probe, 590 .remove = pmcmsptwi_remove, 591 .driver = { 592 .name = DRV_NAME, 593 }, 594}; 595 596module_platform_driver(pmcmsptwi_driver); 597 598MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver"); 599MODULE_LICENSE("GPL"); 600MODULE_ALIAS("platform:" DRV_NAME); 601