diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 5f4bc7008251..fe53207a6ebb 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c | |||
| @@ -183,6 +183,8 @@ struct imx_i2c_struct { | |||
| 183 | unsigned int disable_delay; | 183 | unsigned int disable_delay; |
| 184 | int stopped; | 184 | int stopped; |
| 185 | unsigned int ifdr; /* IMX_I2C_IFDR */ | 185 | unsigned int ifdr; /* IMX_I2C_IFDR */ |
| 186 | unsigned int cur_clk; | ||
| 187 | unsigned int bitrate; | ||
| 186 | const struct imx_i2c_hwdata *hwdata; | 188 | const struct imx_i2c_hwdata *hwdata; |
| 187 | }; | 189 | }; |
| 188 | 190 | ||
| @@ -305,6 +307,48 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx) | |||
| 305 | return 0; | 307 | return 0; |
| 306 | } | 308 | } |
| 307 | 309 | ||
| 310 | static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx) | ||
| 311 | { | ||
| 312 | struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div; | ||
| 313 | unsigned int i2c_clk_rate; | ||
| 314 | unsigned int div; | ||
| 315 | int i; | ||
| 316 | |||
| 317 | /* Divider value calculation */ | ||
| 318 | i2c_clk_rate = clk_get_rate(i2c_imx->clk); | ||
| 319 | if (i2c_imx->cur_clk == i2c_clk_rate) | ||
| 320 | return; | ||
| 321 | else | ||
| 322 | i2c_imx->cur_clk = i2c_clk_rate; | ||
| 323 | |||
| 324 | div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate; | ||
| 325 | if (div < i2c_clk_div[0].div) | ||
| 326 | i = 0; | ||
| 327 | else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div) | ||
| 328 | i = i2c_imx->hwdata->ndivs - 1; | ||
| 329 | else | ||
| 330 | for (i = 0; i2c_clk_div[i].div < div; i++); | ||
| 331 | |||
| 332 | /* Store divider value */ | ||
| 333 | i2c_imx->ifdr = i2c_clk_div[i].val; | ||
| 334 | |||
| 335 | /* | ||
| 336 | * There dummy delay is calculated. | ||
| 337 | * It should be about one I2C clock period long. | ||
| 338 | * This delay is used in I2C bus disable function | ||
| 339 | * to fix chip hardware bug. | ||
| 340 | */ | ||
| 341 | i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div | ||
| 342 | + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); | ||
| 343 | |||
| 344 | #ifdef CONFIG_I2C_DEBUG_BUS | ||
| 345 | dev_dbg(&i2c_imx->adapter.dev, "I2C_CLK=%d, REQ DIV=%d\n", | ||
| 346 | i2c_clk_rate, div); | ||
| 347 | dev_dbg(&i2c_imx->adapter.dev, "IFDR[IC]=0x%x, REAL DIV=%d\n", | ||
| 348 | i2c_clk_div[i].val, i2c_clk_div[i].div); | ||
| 349 | #endif | ||
| 350 | } | ||
| 351 | |||
| 308 | static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) | 352 | static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) |
| 309 | { | 353 | { |
| 310 | unsigned int temp = 0; | 354 | unsigned int temp = 0; |
| @@ -312,6 +356,8 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) | |||
| 312 | 356 | ||
| 313 | dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); | 357 | dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); |
| 314 | 358 | ||
| 359 | i2c_imx_set_clk(i2c_imx); | ||
| 360 | |||
| 315 | result = clk_prepare_enable(i2c_imx->clk); | 361 | result = clk_prepare_enable(i2c_imx->clk); |
| 316 | if (result) | 362 | if (result) |
| 317 | return result; | 363 | return result; |
| @@ -367,45 +413,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) | |||
| 367 | clk_disable_unprepare(i2c_imx->clk); | 413 | clk_disable_unprepare(i2c_imx->clk); |
| 368 | } | 414 | } |
| 369 | 415 | ||
| 370 | static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, | ||
| 371 | unsigned int rate) | ||
| 372 | { | ||
| 373 | struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div; | ||
| 374 | unsigned int i2c_clk_rate; | ||
| 375 | unsigned int div; | ||
| 376 | int i; | ||
| 377 | |||
| 378 | /* Divider value calculation */ | ||
| 379 | i2c_clk_rate = clk_get_rate(i2c_imx->clk); | ||
| 380 | div = (i2c_clk_rate + rate - 1) / rate; | ||
| 381 | if (div < i2c_clk_div[0].div) | ||
| 382 | i = 0; | ||
| 383 | else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div) | ||
| 384 | i = i2c_imx->hwdata->ndivs - 1; | ||
| 385 | else | ||
| 386 | for (i = 0; i2c_clk_div[i].div < div; i++); | ||
| 387 | |||
| 388 | /* Store divider value */ | ||
| 389 | i2c_imx->ifdr = i2c_clk_div[i].val; | ||
| 390 | |||
| 391 | /* | ||
| 392 | * There dummy delay is calculated. | ||
| 393 | * It should be about one I2C clock period long. | ||
| 394 | * This delay is used in I2C bus disable function | ||
| 395 | * to fix chip hardware bug. | ||
| 396 | */ | ||
| 397 | i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div | ||
| 398 | + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); | ||
| 399 | |||
| 400 | /* dev_dbg() can't be used, because adapter is not yet registered */ | ||
| 401 | #ifdef CONFIG_I2C_DEBUG_BUS | ||
| 402 | dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n", | ||
| 403 | __func__, i2c_clk_rate, div); | ||
| 404 | dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n", | ||
| 405 | __func__, i2c_clk_div[i].val, i2c_clk_div[i].div); | ||
| 406 | #endif | ||
| 407 | } | ||
| 408 | |||
| 409 | static irqreturn_t i2c_imx_isr(int irq, void *dev_id) | 416 | static irqreturn_t i2c_imx_isr(int irq, void *dev_id) |
| 410 | { | 417 | { |
| 411 | struct imx_i2c_struct *i2c_imx = dev_id; | 418 | struct imx_i2c_struct *i2c_imx = dev_id; |
| @@ -644,7 +651,6 @@ static int i2c_imx_probe(struct platform_device *pdev) | |||
| 644 | struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev); | 651 | struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| 645 | void __iomem *base; | 652 | void __iomem *base; |
| 646 | int irq, ret; | 653 | int irq, ret; |
| 647 | u32 bitrate; | ||
| 648 | 654 | ||
| 649 | dev_dbg(&pdev->dev, "<%s>\n", __func__); | 655 | dev_dbg(&pdev->dev, "<%s>\n", __func__); |
| 650 | 656 | ||
| @@ -708,12 +714,11 @@ static int i2c_imx_probe(struct platform_device *pdev) | |||
| 708 | i2c_set_adapdata(&i2c_imx->adapter, i2c_imx); | 714 | i2c_set_adapdata(&i2c_imx->adapter, i2c_imx); |
| 709 | 715 | ||
| 710 | /* Set up clock divider */ | 716 | /* Set up clock divider */ |
| 711 | bitrate = IMX_I2C_BIT_RATE; | 717 | i2c_imx->bitrate = IMX_I2C_BIT_RATE; |
| 712 | ret = of_property_read_u32(pdev->dev.of_node, | 718 | ret = of_property_read_u32(pdev->dev.of_node, |
| 713 | "clock-frequency", &bitrate); | 719 | "clock-frequency", &i2c_imx->bitrate); |
| 714 | if (ret < 0 && pdata && pdata->bitrate) | 720 | if (ret < 0 && pdata && pdata->bitrate) |
| 715 | bitrate = pdata->bitrate; | 721 | i2c_imx->bitrate = pdata->bitrate; |
| 716 | i2c_imx_set_clk(i2c_imx, bitrate); | ||
| 717 | 722 | ||
| 718 | /* Set up chip registers to defaults */ | 723 | /* Set up chip registers to defaults */ |
| 719 | imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN, | 724 | imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN, |
