diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:19 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:19 -0400 |
| commit | 500b9fc922cbec572f4fd1436533bfaed5011262 (patch) | |
| tree | aac4b7de0871e66740aeaf3510f7a59280026592 /drivers/i2c | |
| parent | f165eb77f49cb6f6e86e2f2f09183904b2965d19 (diff) | |
| parent | beccb12f6fbcc73339f127ff1f00638f076c933f (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/genesis-2.6 into devel-stable
Conflicts:
drivers/net/irda/sh_irda.c
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 121 |
2 files changed, 85 insertions, 38 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index bceafbfa7268..29e01f6238a7 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -549,7 +549,7 @@ config I2C_SH7760 | |||
| 549 | 549 | ||
| 550 | config I2C_SH_MOBILE | 550 | config I2C_SH_MOBILE |
| 551 | tristate "SuperH Mobile I2C Controller" | 551 | tristate "SuperH Mobile I2C Controller" |
| 552 | depends on SUPERH | 552 | depends on SUPERH || ARCH_SHMOBILE |
| 553 | help | 553 | help |
| 554 | If you say yes to this option, support will be included for the | 554 | If you say yes to this option, support will be included for the |
| 555 | built-in I2C interface on the Renesas SH-Mobile processor. | 555 | built-in I2C interface on the Renesas SH-Mobile processor. |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index ffb405d7c6f2..598c49acaeb5 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
| @@ -119,8 +119,10 @@ struct sh_mobile_i2c_data { | |||
| 119 | struct i2c_adapter adap; | 119 | struct i2c_adapter adap; |
| 120 | 120 | ||
| 121 | struct clk *clk; | 121 | struct clk *clk; |
| 122 | u_int8_t icic; | ||
| 122 | u_int8_t iccl; | 123 | u_int8_t iccl; |
| 123 | u_int8_t icch; | 124 | u_int8_t icch; |
| 125 | u_int8_t flags; | ||
| 124 | 126 | ||
| 125 | spinlock_t lock; | 127 | spinlock_t lock; |
| 126 | wait_queue_head_t wait; | 128 | wait_queue_head_t wait; |
| @@ -129,15 +131,17 @@ struct sh_mobile_i2c_data { | |||
| 129 | int sr; | 131 | int sr; |
| 130 | }; | 132 | }; |
| 131 | 133 | ||
| 134 | #define IIC_FLAG_HAS_ICIC67 (1 << 0) | ||
| 135 | |||
| 132 | #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ | 136 | #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ |
| 133 | 137 | ||
| 134 | /* Register offsets */ | 138 | /* Register offsets */ |
| 135 | #define ICDR(pd) (pd->reg + 0x00) | 139 | #define ICDR 0x00 |
| 136 | #define ICCR(pd) (pd->reg + 0x04) | 140 | #define ICCR 0x04 |
| 137 | #define ICSR(pd) (pd->reg + 0x08) | 141 | #define ICSR 0x08 |
| 138 | #define ICIC(pd) (pd->reg + 0x0c) | 142 | #define ICIC 0x0c |
| 139 | #define ICCL(pd) (pd->reg + 0x10) | 143 | #define ICCL 0x10 |
| 140 | #define ICCH(pd) (pd->reg + 0x14) | 144 | #define ICCH 0x14 |
| 141 | 145 | ||
| 142 | /* Register bits */ | 146 | /* Register bits */ |
| 143 | #define ICCR_ICE 0x80 | 147 | #define ICCR_ICE 0x80 |
| @@ -155,11 +159,32 @@ struct sh_mobile_i2c_data { | |||
| 155 | #define ICSR_WAIT 0x02 | 159 | #define ICSR_WAIT 0x02 |
| 156 | #define ICSR_DTE 0x01 | 160 | #define ICSR_DTE 0x01 |
| 157 | 161 | ||
| 162 | #define ICIC_ICCLB8 0x80 | ||
| 163 | #define ICIC_ICCHB8 0x40 | ||
| 158 | #define ICIC_ALE 0x08 | 164 | #define ICIC_ALE 0x08 |
| 159 | #define ICIC_TACKE 0x04 | 165 | #define ICIC_TACKE 0x04 |
| 160 | #define ICIC_WAITE 0x02 | 166 | #define ICIC_WAITE 0x02 |
| 161 | #define ICIC_DTEE 0x01 | 167 | #define ICIC_DTEE 0x01 |
| 162 | 168 | ||
| 169 | static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) | ||
| 170 | { | ||
| 171 | if (offs == ICIC) | ||
| 172 | data |= pd->icic; | ||
| 173 | |||
| 174 | iowrite8(data, pd->reg + offs); | ||
| 175 | } | ||
| 176 | |||
| 177 | static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs) | ||
| 178 | { | ||
| 179 | return ioread8(pd->reg + offs); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs, | ||
| 183 | unsigned char set, unsigned char clr) | ||
| 184 | { | ||
| 185 | iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); | ||
| 186 | } | ||
| 187 | |||
| 163 | static void activate_ch(struct sh_mobile_i2c_data *pd) | 188 | static void activate_ch(struct sh_mobile_i2c_data *pd) |
| 164 | { | 189 | { |
| 165 | unsigned long i2c_clk; | 190 | unsigned long i2c_clk; |
| @@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) | |||
| 187 | else | 212 | else |
| 188 | pd->iccl = (u_int8_t)(num/denom); | 213 | pd->iccl = (u_int8_t)(num/denom); |
| 189 | 214 | ||
| 215 | /* one more bit of ICCL in ICIC */ | ||
| 216 | if (pd->flags & IIC_FLAG_HAS_ICIC67) { | ||
| 217 | if ((num/denom) > 0xff) | ||
| 218 | pd->icic |= ICIC_ICCLB8; | ||
| 219 | else | ||
| 220 | pd->icic &= ~ICIC_ICCLB8; | ||
| 221 | } | ||
| 222 | |||
| 190 | /* Calculate the value for icch. From the data sheet: | 223 | /* Calculate the value for icch. From the data sheet: |
| 191 | icch = (p clock / transfer rate) * (H / (L + H)) */ | 224 | icch = (p clock / transfer rate) * (H / (L + H)) */ |
| 192 | num = i2c_clk * 4; | 225 | num = i2c_clk * 4; |
| @@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) | |||
| 196 | else | 229 | else |
| 197 | pd->icch = (u_int8_t)(num/denom); | 230 | pd->icch = (u_int8_t)(num/denom); |
| 198 | 231 | ||
| 232 | /* one more bit of ICCH in ICIC */ | ||
| 233 | if (pd->flags & IIC_FLAG_HAS_ICIC67) { | ||
| 234 | if ((num/denom) > 0xff) | ||
| 235 | pd->icic |= ICIC_ICCHB8; | ||
| 236 | else | ||
| 237 | pd->icic &= ~ICIC_ICCHB8; | ||
| 238 | } | ||
| 239 | |||
| 199 | /* Enable channel and configure rx ack */ | 240 | /* Enable channel and configure rx ack */ |
| 200 | iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); | 241 | iic_set_clr(pd, ICCR, ICCR_ICE, 0); |
| 201 | 242 | ||
| 202 | /* Mask all interrupts */ | 243 | /* Mask all interrupts */ |
| 203 | iowrite8(0, ICIC(pd)); | 244 | iic_wr(pd, ICIC, 0); |
| 204 | 245 | ||
| 205 | /* Set the clock */ | 246 | /* Set the clock */ |
| 206 | iowrite8(pd->iccl, ICCL(pd)); | 247 | iic_wr(pd, ICCL, pd->iccl); |
| 207 | iowrite8(pd->icch, ICCH(pd)); | 248 | iic_wr(pd, ICCH, pd->icch); |
| 208 | } | 249 | } |
| 209 | 250 | ||
| 210 | static void deactivate_ch(struct sh_mobile_i2c_data *pd) | 251 | static void deactivate_ch(struct sh_mobile_i2c_data *pd) |
| 211 | { | 252 | { |
| 212 | /* Clear/disable interrupts */ | 253 | /* Clear/disable interrupts */ |
| 213 | iowrite8(0, ICSR(pd)); | 254 | iic_wr(pd, ICSR, 0); |
| 214 | iowrite8(0, ICIC(pd)); | 255 | iic_wr(pd, ICIC, 0); |
| 215 | 256 | ||
| 216 | /* Disable channel */ | 257 | /* Disable channel */ |
| 217 | iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); | 258 | iic_set_clr(pd, ICCR, 0, ICCR_ICE); |
| 218 | 259 | ||
| 219 | /* Disable clock and mark device as idle */ | 260 | /* Disable clock and mark device as idle */ |
| 220 | clk_disable(pd->clk); | 261 | clk_disable(pd->clk); |
| @@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, | |||
| 233 | 274 | ||
| 234 | switch (op) { | 275 | switch (op) { |
| 235 | case OP_START: /* issue start and trigger DTE interrupt */ | 276 | case OP_START: /* issue start and trigger DTE interrupt */ |
| 236 | iowrite8(0x94, ICCR(pd)); | 277 | iic_wr(pd, ICCR, 0x94); |
| 237 | break; | 278 | break; |
| 238 | case OP_TX_FIRST: /* disable DTE interrupt and write data */ | 279 | case OP_TX_FIRST: /* disable DTE interrupt and write data */ |
| 239 | iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); | 280 | iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
| 240 | iowrite8(data, ICDR(pd)); | 281 | iic_wr(pd, ICDR, data); |
| 241 | break; | 282 | break; |
| 242 | case OP_TX: /* write data */ | 283 | case OP_TX: /* write data */ |
| 243 | iowrite8(data, ICDR(pd)); | 284 | iic_wr(pd, ICDR, data); |
| 244 | break; | 285 | break; |
| 245 | case OP_TX_STOP: /* write data and issue a stop afterwards */ | 286 | case OP_TX_STOP: /* write data and issue a stop afterwards */ |
| 246 | iowrite8(data, ICDR(pd)); | 287 | iic_wr(pd, ICDR, data); |
| 247 | iowrite8(0x90, ICCR(pd)); | 288 | iic_wr(pd, ICCR, 0x90); |
| 248 | break; | 289 | break; |
| 249 | case OP_TX_TO_RX: /* select read mode */ | 290 | case OP_TX_TO_RX: /* select read mode */ |
| 250 | iowrite8(0x81, ICCR(pd)); | 291 | iic_wr(pd, ICCR, 0x81); |
| 251 | break; | 292 | break; |
| 252 | case OP_RX: /* just read data */ | 293 | case OP_RX: /* just read data */ |
| 253 | ret = ioread8(ICDR(pd)); | 294 | ret = iic_rd(pd, ICDR); |
| 254 | break; | 295 | break; |
| 255 | case OP_RX_STOP: /* enable DTE interrupt, issue stop */ | 296 | case OP_RX_STOP: /* enable DTE interrupt, issue stop */ |
| 256 | iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, | 297 | iic_wr(pd, ICIC, |
| 257 | ICIC(pd)); | 298 | ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
| 258 | iowrite8(0xc0, ICCR(pd)); | 299 | iic_wr(pd, ICCR, 0xc0); |
| 259 | break; | 300 | break; |
| 260 | case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ | 301 | case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ |
| 261 | iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, | 302 | iic_wr(pd, ICIC, |
| 262 | ICIC(pd)); | 303 | ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
| 263 | ret = ioread8(ICDR(pd)); | 304 | ret = iic_rd(pd, ICDR); |
| 264 | iowrite8(0xc0, ICCR(pd)); | 305 | iic_wr(pd, ICCR, 0xc0); |
| 265 | break; | 306 | break; |
| 266 | } | 307 | } |
| 267 | 308 | ||
| @@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
| 367 | unsigned char sr; | 408 | unsigned char sr; |
| 368 | int wakeup; | 409 | int wakeup; |
| 369 | 410 | ||
| 370 | sr = ioread8(ICSR(pd)); | 411 | sr = iic_rd(pd, ICSR); |
| 371 | pd->sr |= sr; /* remember state */ | 412 | pd->sr |= sr; /* remember state */ |
| 372 | 413 | ||
| 373 | dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, | 414 | dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, |
| @@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
| 376 | 417 | ||
| 377 | if (sr & (ICSR_AL | ICSR_TACK)) { | 418 | if (sr & (ICSR_AL | ICSR_TACK)) { |
| 378 | /* don't interrupt transaction - continue to issue stop */ | 419 | /* don't interrupt transaction - continue to issue stop */ |
| 379 | iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd)); | 420 | iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK)); |
| 380 | wakeup = 0; | 421 | wakeup = 0; |
| 381 | } else if (pd->msg->flags & I2C_M_RD) | 422 | } else if (pd->msg->flags & I2C_M_RD) |
| 382 | wakeup = sh_mobile_i2c_isr_rx(pd); | 423 | wakeup = sh_mobile_i2c_isr_rx(pd); |
| @@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
| 384 | wakeup = sh_mobile_i2c_isr_tx(pd); | 425 | wakeup = sh_mobile_i2c_isr_tx(pd); |
| 385 | 426 | ||
| 386 | if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ | 427 | if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ |
| 387 | iowrite8(sr & ~ICSR_WAIT, ICSR(pd)); | 428 | iic_wr(pd, ICSR, sr & ~ICSR_WAIT); |
| 388 | 429 | ||
| 389 | if (wakeup) { | 430 | if (wakeup) { |
| 390 | pd->sr |= SW_DONE; | 431 | pd->sr |= SW_DONE; |
| @@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) | |||
| 402 | } | 443 | } |
| 403 | 444 | ||
| 404 | /* Initialize channel registers */ | 445 | /* Initialize channel registers */ |
| 405 | iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); | 446 | iic_set_clr(pd, ICCR, 0, ICCR_ICE); |
| 406 | 447 | ||
| 407 | /* Enable channel and configure rx ack */ | 448 | /* Enable channel and configure rx ack */ |
| 408 | iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); | 449 | iic_set_clr(pd, ICCR, ICCR_ICE, 0); |
| 409 | 450 | ||
| 410 | /* Set the clock */ | 451 | /* Set the clock */ |
| 411 | iowrite8(pd->iccl, ICCL(pd)); | 452 | iic_wr(pd, ICCL, pd->iccl); |
| 412 | iowrite8(pd->icch, ICCH(pd)); | 453 | iic_wr(pd, ICCH, pd->icch); |
| 413 | 454 | ||
| 414 | pd->msg = usr_msg; | 455 | pd->msg = usr_msg; |
| 415 | pd->pos = -1; | 456 | pd->pos = -1; |
| 416 | pd->sr = 0; | 457 | pd->sr = 0; |
| 417 | 458 | ||
| 418 | /* Enable all interrupts to begin with */ | 459 | /* Enable all interrupts to begin with */ |
| 419 | iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); | 460 | iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
| 420 | return 0; | 461 | return 0; |
| 421 | } | 462 | } |
| 422 | 463 | ||
| @@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | |||
| 451 | 492 | ||
| 452 | retry_count = 1000; | 493 | retry_count = 1000; |
| 453 | again: | 494 | again: |
| 454 | val = ioread8(ICSR(pd)); | 495 | val = iic_rd(pd, ICSR); |
| 455 | 496 | ||
| 456 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); | 497 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); |
| 457 | 498 | ||
| @@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | |||
| 576 | goto err_irq; | 617 | goto err_irq; |
| 577 | } | 618 | } |
| 578 | 619 | ||
| 620 | /* The IIC blocks on SH-Mobile ARM processors | ||
| 621 | * come with two new bits in ICIC. | ||
| 622 | */ | ||
| 623 | if (size > 0x17) | ||
| 624 | pd->flags |= IIC_FLAG_HAS_ICIC67; | ||
| 625 | |||
| 579 | /* Enable Runtime PM for this device. | 626 | /* Enable Runtime PM for this device. |
| 580 | * | 627 | * |
| 581 | * Also tell the Runtime PM core to ignore children | 628 | * Also tell the Runtime PM core to ignore children |
