Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: mediatek: send i2c master code at 400k

The speed of sending i2c master code in high-speed mode depends on
source clock, clock-div and TIMING register. The source clock and
clock-div of different SoC are not all the same. In order to send
i2c master code at 400k in high-speed mode, a appropriate value
should be set to TIMING register for a certain source clock and
clock-div.

Signed-off-by: Jun Gao <jun.gao@mediatek.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Jun Gao and committed by
Wolfram Sang
f2326401 16f73eb0

+46 -19
+46 -19
drivers/i2c/busses/i2c-mt65xx.c
··· 50 50 #define I2C_FS_START_CON 0x1800 51 51 #define I2C_TIME_CLR_VALUE 0x0000 52 52 #define I2C_TIME_DEFAULT_VALUE 0x0003 53 - #define I2C_FS_TIME_INIT_VALUE 0x1303 54 53 #define I2C_WRRD_TRANAC_VALUE 0x0002 55 54 #define I2C_RD_TRANAC_VALUE 0x0001 56 55 ··· 153 154 bool use_push_pull; /* IO config push-pull mode */ 154 155 155 156 u16 irq_stat; /* interrupt status */ 157 + unsigned int clk_src_div; 156 158 unsigned int speed_hz; /* The speed in transfer */ 157 159 enum mtk_trans_op op; 158 160 u16 timing_reg; ··· 285 285 * less than or equal to i2c->speed_hz. The calculation try to get 286 286 * sample_cnt and step_cn 287 287 */ 288 - static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk, 289 - unsigned int clock_div) 288 + static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, 289 + unsigned int target_speed, 290 + unsigned int *timing_step_cnt, 291 + unsigned int *timing_sample_cnt) 290 292 { 291 - unsigned int clk_src; 292 293 unsigned int step_cnt; 293 294 unsigned int sample_cnt; 294 295 unsigned int max_step_cnt; 295 - unsigned int target_speed; 296 296 unsigned int base_sample_cnt = MAX_SAMPLE_CNT_DIV; 297 297 unsigned int base_step_cnt; 298 298 unsigned int opt_div; 299 299 unsigned int best_mul; 300 300 unsigned int cnt_mul; 301 - 302 - clk_src = parent_clk / clock_div; 303 - target_speed = i2c->speed_hz; 304 301 305 302 if (target_speed > MAX_HS_MODE_SPEED) 306 303 target_speed = MAX_HS_MODE_SPEED; ··· 344 347 return -EINVAL; 345 348 } 346 349 347 - step_cnt--; 348 - sample_cnt--; 350 + *timing_step_cnt = step_cnt - 1; 351 + *timing_sample_cnt = sample_cnt - 1; 352 + 353 + return 0; 354 + } 355 + 356 + static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk) 357 + { 358 + unsigned int clk_src; 359 + unsigned int step_cnt; 360 + unsigned int sample_cnt; 361 + unsigned int target_speed; 362 + int ret; 363 + 364 + clk_src = parent_clk / i2c->clk_src_div; 365 + target_speed = i2c->speed_hz; 349 366 350 367 if (target_speed > MAX_FS_MODE_SPEED) { 368 + /* Set master code speed register */ 369 + ret = mtk_i2c_calculate_speed(i2c, clk_src, MAX_FS_MODE_SPEED, 370 + &step_cnt, &sample_cnt); 371 + if (ret < 0) 372 + return ret; 373 + 374 + i2c->timing_reg = (sample_cnt << 8) | step_cnt; 375 + 351 376 /* Set the high speed mode register */ 352 - i2c->timing_reg = I2C_FS_TIME_INIT_VALUE; 377 + ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed, 378 + &step_cnt, &sample_cnt); 379 + if (ret < 0) 380 + return ret; 381 + 353 382 i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE | 354 383 (sample_cnt << 12) | (step_cnt << 8); 355 384 } else { 356 - i2c->timing_reg = (sample_cnt << 8) | (step_cnt << 0); 385 + ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed, 386 + &step_cnt, &sample_cnt); 387 + if (ret < 0) 388 + return ret; 389 + 390 + i2c->timing_reg = (sample_cnt << 8) | step_cnt; 391 + 357 392 /* Disable the high speed transaction */ 358 393 i2c->high_speed_reg = I2C_TIME_CLR_VALUE; 359 394 } ··· 676 647 .functionality = mtk_i2c_functionality, 677 648 }; 678 649 679 - static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c, 680 - unsigned int *clk_src_div) 650 + static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c) 681 651 { 682 652 int ret; 683 653 ··· 684 656 if (ret < 0) 685 657 i2c->speed_hz = I2C_DEFAULT_SPEED; 686 658 687 - ret = of_property_read_u32(np, "clock-div", clk_src_div); 659 + ret = of_property_read_u32(np, "clock-div", &i2c->clk_src_div); 688 660 if (ret < 0) 689 661 return ret; 690 662 691 - if (*clk_src_div == 0) 663 + if (i2c->clk_src_div == 0) 692 664 return -EINVAL; 693 665 694 666 i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic"); ··· 704 676 int ret = 0; 705 677 struct mtk_i2c *i2c; 706 678 struct clk *clk; 707 - unsigned int clk_src_div; 708 679 struct resource *res; 709 680 int irq; 710 681 ··· 711 684 if (!i2c) 712 685 return -ENOMEM; 713 686 714 - ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c, &clk_src_div); 687 + ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c); 715 688 if (ret) 716 689 return -EINVAL; 717 690 ··· 772 745 773 746 strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name)); 774 747 775 - ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk), clk_src_div); 748 + ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk)); 776 749 if (ret) { 777 750 dev_err(&pdev->dev, "Failed to set the speed.\n"); 778 751 return -EINVAL;