aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVirupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>2012-06-25 08:26:07 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-07-09 05:55:30 -0400
commit51a0c8d0b8a877f41e9be62fb1e946ec682611c1 (patch)
treea49df3226e64c16e61b00adcf417e836019d7c97 /drivers
parent419408edc90ee50d50323227d4dd73d6d22dc744 (diff)
i2c-nomadik: Add 10-bit addressing support
Signed-off-by: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com> Signed-off-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 6db453fe68e6..e6b93f3ca867 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -276,15 +276,32 @@ exit:
276/** 276/**
277 * load_i2c_mcr_reg() - load the MCR register 277 * load_i2c_mcr_reg() - load the MCR register
278 * @dev: private data of controller 278 * @dev: private data of controller
279 * @flags: message flags
279 */ 280 */
280static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev) 281static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev, u16 flags)
281{ 282{
282 u32 mcr = 0; 283 u32 mcr = 0;
284 unsigned short slave_adr_3msb_bits;
283 285
284 /* 7-bit address transaction */
285 mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
286 mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1); 286 mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
287 287
288 if (unlikely(flags & I2C_M_TEN)) {
289 /* 10-bit address transaction */
290 mcr |= GEN_MASK(2, I2C_MCR_AM, 12);
291 /*
292 * Get the top 3 bits.
293 * EA10 represents extended address in MCR. This includes
294 * the extension (MSB bits) of the 7 bit address loaded
295 * in A7
296 */
297 slave_adr_3msb_bits = (dev->cli.slave_adr >> 7) & 0x7;
298
299 mcr |= GEN_MASK(slave_adr_3msb_bits, I2C_MCR_EA10, 8);
300 } else {
301 /* 7-bit address transaction */
302 mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
303 }
304
288 /* start byte procedure not applied */ 305 /* start byte procedure not applied */
289 mcr |= GEN_MASK(0, I2C_MCR_SB, 11); 306 mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
290 307
@@ -381,19 +398,20 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
381/** 398/**
382 * read_i2c() - Read from I2C client device 399 * read_i2c() - Read from I2C client device
383 * @dev: private data of I2C Driver 400 * @dev: private data of I2C Driver
401 * @flags: message flags
384 * 402 *
385 * This function reads from i2c client device when controller is in 403 * This function reads from i2c client device when controller is in
386 * master mode. There is a completion timeout. If there is no transfer 404 * master mode. There is a completion timeout. If there is no transfer
387 * before timeout error is returned. 405 * before timeout error is returned.
388 */ 406 */
389static int read_i2c(struct nmk_i2c_dev *dev) 407static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
390{ 408{
391 u32 status = 0; 409 u32 status = 0;
392 u32 mcr; 410 u32 mcr;
393 u32 irq_mask = 0; 411 u32 irq_mask = 0;
394 int timeout; 412 int timeout;
395 413
396 mcr = load_i2c_mcr_reg(dev); 414 mcr = load_i2c_mcr_reg(dev, flags);
397 writel(mcr, dev->virtbase + I2C_MCR); 415 writel(mcr, dev->virtbase + I2C_MCR);
398 416
399 /* load the current CR value */ 417 /* load the current CR value */
@@ -459,17 +477,18 @@ static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
459/** 477/**
460 * write_i2c() - Write data to I2C client. 478 * write_i2c() - Write data to I2C client.
461 * @dev: private data of I2C Driver 479 * @dev: private data of I2C Driver
480 * @flags: message flags
462 * 481 *
463 * This function writes data to I2C client 482 * This function writes data to I2C client
464 */ 483 */
465static int write_i2c(struct nmk_i2c_dev *dev) 484static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
466{ 485{
467 u32 status = 0; 486 u32 status = 0;
468 u32 mcr; 487 u32 mcr;
469 u32 irq_mask = 0; 488 u32 irq_mask = 0;
470 int timeout; 489 int timeout;
471 490
472 mcr = load_i2c_mcr_reg(dev); 491 mcr = load_i2c_mcr_reg(dev, flags);
473 492
474 writel(mcr, dev->virtbase + I2C_MCR); 493 writel(mcr, dev->virtbase + I2C_MCR);
475 494
@@ -538,11 +557,11 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
538 if (flags & I2C_M_RD) { 557 if (flags & I2C_M_RD) {
539 /* read operation */ 558 /* read operation */
540 dev->cli.operation = I2C_READ; 559 dev->cli.operation = I2C_READ;
541 status = read_i2c(dev); 560 status = read_i2c(dev, flags);
542 } else { 561 } else {
543 /* write operation */ 562 /* write operation */
544 dev->cli.operation = I2C_WRITE; 563 dev->cli.operation = I2C_WRITE;
545 status = write_i2c(dev); 564 status = write_i2c(dev, flags);
546 } 565 }
547 566
548 if (status || (dev->result)) { 567 if (status || (dev->result)) {
@@ -644,13 +663,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
644 setup_i2c_controller(dev); 663 setup_i2c_controller(dev);
645 664
646 for (i = 0; i < num_msgs; i++) { 665 for (i = 0; i < num_msgs; i++) {
647 if (unlikely(msgs[i].flags & I2C_M_TEN)) {
648 dev_err(&dev->adev->dev,
649 "10 bit addressing not supported\n");
650
651 status = -EINVAL;
652 goto out;
653 }
654 dev->cli.slave_adr = msgs[i].addr; 666 dev->cli.slave_adr = msgs[i].addr;
655 dev->cli.buffer = msgs[i].buf; 667 dev->cli.buffer = msgs[i].buf;
656 dev->cli.count = msgs[i].len; 668 dev->cli.count = msgs[i].len;
@@ -891,7 +903,7 @@ static const struct dev_pm_ops nmk_i2c_pm = {
891 903
892static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap) 904static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
893{ 905{
894 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 906 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
895} 907}
896 908
897static const struct i2c_algorithm nmk_i2c_algo = { 909static const struct i2c_algorithm nmk_i2c_algo = {