aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-tegra.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 12:41:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 12:41:53 -0500
commit52caa59ed335616c5254adff7911465a57ed9f14 (patch)
treede0a1e91850c9e439e82f83f228d89fee3b90b09 /drivers/i2c/busses/i2c-tegra.c
parent4c8c225abf972ce422c241579ce1d4d27eaeb166 (diff)
parent55827f4aa6442ddd1d6a4e1e32f2f457eb113c22 (diff)
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang: "Highlights: - new drivers for Intel ismt & Broadcom bcm2835 - a number of drivers got support for more variants and mostly got cleaned up on the way (sis630, i801, at91, tegra, designware) - i2c got rid of all *_set_drvdata(..., NULL) on remove/probe failure - removed the i2c_smbus_process_call from the core since there are no users - mxs can now switch between PIO and DMA depending on the message size and the bus speed can now be arbitrary In addition, there is the usual bunch of fixes, cleanups, devm_* conversions, etc" Fixed conflict (and buggy devm_* conversion) in i2c-s3c2410.c * 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (39 commits) i2c: Remove unneeded xxx_set_drvdata(..., NULL) calls i2c: pxa: remove incorrect __exit annotations i2c: ocores: Fix pointer to integer cast warning i2c: tegra: remove warning dump if timeout happen in transfer i2c: fix i2c-ismt.c printk format warning i2c: i801: Add Device IDs for Intel Wellsburg PCH i2c: add bcm2835 driver i2c: ismt: Add Seth and Myself as maintainers i2c: sis630: checkpatch cleanup i2c: sis630: display unsigned hex i2c: sis630: use hex to constants for SMBus commands i2c: sis630: fix behavior after collision i2c: sis630: clear sticky bits i2c: sis630: Add SIS964 support i2c: isch: Add module parameter for backbone clock rate if divider is unset i2c: at91: fix unsed variable warning when building with !CONFIG_OF i2c: Adding support for Intel iSMT SMBus 2.0 host controller i2c: sh_mobile: don't send a stop condition by default inside transfers i2c: sh_mobile: eliminate an open-coded "goto" loop i2c: sh_mobile: fix timeout error handling ...
Diffstat (limited to 'drivers/i2c/busses/i2c-tegra.c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f0d9923323ea..36704e3ab3fa 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -70,6 +70,8 @@
70#define I2C_INT_TX_FIFO_DATA_REQ (1<<1) 70#define I2C_INT_TX_FIFO_DATA_REQ (1<<1)
71#define I2C_INT_RX_FIFO_DATA_REQ (1<<0) 71#define I2C_INT_RX_FIFO_DATA_REQ (1<<0)
72#define I2C_CLK_DIVISOR 0x06c 72#define I2C_CLK_DIVISOR 0x06c
73#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT 16
74#define I2C_CLK_MULTIPLIER_STD_FAST_MODE 8
73 75
74#define DVC_CTRL_REG1 0x000 76#define DVC_CTRL_REG1 0x000
75#define DVC_CTRL_REG1_INTR_EN (1<<10) 77#define DVC_CTRL_REG1_INTR_EN (1<<10)
@@ -116,10 +118,23 @@ enum msg_end_type {
116/** 118/**
117 * struct tegra_i2c_hw_feature : Different HW support on Tegra 119 * struct tegra_i2c_hw_feature : Different HW support on Tegra
118 * @has_continue_xfer_support: Continue transfer supports. 120 * @has_continue_xfer_support: Continue transfer supports.
121 * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
122 * complete interrupt per packet basis.
123 * @has_single_clk_source: The i2c controller has single clock source. Tegra30
124 * and earlier Socs has two clock sources i.e. div-clk and
125 * fast-clk.
126 * @clk_divisor_hs_mode: Clock divisor in HS mode.
127 * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
128 * applicable if there is no fast clock source i.e. single clock
129 * source.
119 */ 130 */
120 131
121struct tegra_i2c_hw_feature { 132struct tegra_i2c_hw_feature {
122 bool has_continue_xfer_support; 133 bool has_continue_xfer_support;
134 bool has_per_pkt_xfer_complete_irq;
135 bool has_single_clk_source;
136 int clk_divisor_hs_mode;
137 int clk_divisor_std_fast_mode;
123}; 138};
124 139
125/** 140/**
@@ -365,11 +380,13 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
365static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev) 380static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
366{ 381{
367 int ret; 382 int ret;
368 ret = clk_prepare_enable(i2c_dev->fast_clk); 383 if (!i2c_dev->hw->has_single_clk_source) {
369 if (ret < 0) { 384 ret = clk_prepare_enable(i2c_dev->fast_clk);
370 dev_err(i2c_dev->dev, 385 if (ret < 0) {
371 "Enabling fast clk failed, err %d\n", ret); 386 dev_err(i2c_dev->dev,
372 return ret; 387 "Enabling fast clk failed, err %d\n", ret);
388 return ret;
389 }
373 } 390 }
374 ret = clk_prepare_enable(i2c_dev->div_clk); 391 ret = clk_prepare_enable(i2c_dev->div_clk);
375 if (ret < 0) { 392 if (ret < 0) {
@@ -383,13 +400,16 @@ static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
383static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev) 400static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
384{ 401{
385 clk_disable_unprepare(i2c_dev->div_clk); 402 clk_disable_unprepare(i2c_dev->div_clk);
386 clk_disable_unprepare(i2c_dev->fast_clk); 403 if (!i2c_dev->hw->has_single_clk_source)
404 clk_disable_unprepare(i2c_dev->fast_clk);
387} 405}
388 406
389static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) 407static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
390{ 408{
391 u32 val; 409 u32 val;
392 int err = 0; 410 int err = 0;
411 int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE;
412 u32 clk_divisor;
393 413
394 tegra_i2c_clock_enable(i2c_dev); 414 tegra_i2c_clock_enable(i2c_dev);
395 415
@@ -404,7 +424,15 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
404 (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); 424 (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
405 i2c_writel(i2c_dev, val, I2C_CNFG); 425 i2c_writel(i2c_dev, val, I2C_CNFG);
406 i2c_writel(i2c_dev, 0, I2C_INT_MASK); 426 i2c_writel(i2c_dev, 0, I2C_INT_MASK);
407 clk_set_rate(i2c_dev->div_clk, i2c_dev->bus_clk_rate * 8); 427
428 clk_multiplier *= (i2c_dev->hw->clk_divisor_std_fast_mode + 1);
429 clk_set_rate(i2c_dev->div_clk, i2c_dev->bus_clk_rate * clk_multiplier);
430
431 /* Make sure clock divisor programmed correctly */
432 clk_divisor = i2c_dev->hw->clk_divisor_hs_mode;
433 clk_divisor |= i2c_dev->hw->clk_divisor_std_fast_mode <<
434 I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
435 i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
408 436
409 if (!i2c_dev->is_dvc) { 437 if (!i2c_dev->is_dvc) {
410 u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG); 438 u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -546,6 +574,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
546 tegra_i2c_fill_tx_fifo(i2c_dev); 574 tegra_i2c_fill_tx_fifo(i2c_dev);
547 575
548 int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; 576 int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
577 if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
578 int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
549 if (msg->flags & I2C_M_RD) 579 if (msg->flags & I2C_M_RD)
550 int_mask |= I2C_INT_RX_FIFO_DATA_REQ; 580 int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
551 else if (i2c_dev->msg_buf_remaining) 581 else if (i2c_dev->msg_buf_remaining)
@@ -557,7 +587,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
557 ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT); 587 ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT);
558 tegra_i2c_mask_irq(i2c_dev, int_mask); 588 tegra_i2c_mask_irq(i2c_dev, int_mask);
559 589
560 if (WARN_ON(ret == 0)) { 590 if (ret == 0) {
561 dev_err(i2c_dev->dev, "i2c transfer timed out\n"); 591 dev_err(i2c_dev->dev, "i2c transfer timed out\n");
562 592
563 tegra_i2c_init(i2c_dev); 593 tegra_i2c_init(i2c_dev);
@@ -633,15 +663,32 @@ static const struct i2c_algorithm tegra_i2c_algo = {
633 663
634static const struct tegra_i2c_hw_feature tegra20_i2c_hw = { 664static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
635 .has_continue_xfer_support = false, 665 .has_continue_xfer_support = false,
666 .has_per_pkt_xfer_complete_irq = false,
667 .has_single_clk_source = false,
668 .clk_divisor_hs_mode = 3,
669 .clk_divisor_std_fast_mode = 0,
636}; 670};
637 671
638static const struct tegra_i2c_hw_feature tegra30_i2c_hw = { 672static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
639 .has_continue_xfer_support = true, 673 .has_continue_xfer_support = true,
674 .has_per_pkt_xfer_complete_irq = false,
675 .has_single_clk_source = false,
676 .clk_divisor_hs_mode = 3,
677 .clk_divisor_std_fast_mode = 0,
678};
679
680static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
681 .has_continue_xfer_support = true,
682 .has_per_pkt_xfer_complete_irq = true,
683 .has_single_clk_source = true,
684 .clk_divisor_hs_mode = 1,
685 .clk_divisor_std_fast_mode = 0x19,
640}; 686};
641 687
642#if defined(CONFIG_OF) 688#if defined(CONFIG_OF)
643/* Match table for of_platform binding */ 689/* Match table for of_platform binding */
644static const struct of_device_id tegra_i2c_of_match[] = { 690static const struct of_device_id tegra_i2c_of_match[] = {
691 { .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
645 { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, }, 692 { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
646 { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, }, 693 { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
647 { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, }, 694 { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
@@ -685,12 +732,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
685 return PTR_ERR(div_clk); 732 return PTR_ERR(div_clk);
686 } 733 }
687 734
688 fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
689 if (IS_ERR(fast_clk)) {
690 dev_err(&pdev->dev, "missing bus clock");
691 return PTR_ERR(fast_clk);
692 }
693
694 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 735 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
695 if (!i2c_dev) { 736 if (!i2c_dev) {
696 dev_err(&pdev->dev, "Could not allocate struct tegra_i2c_dev"); 737 dev_err(&pdev->dev, "Could not allocate struct tegra_i2c_dev");
@@ -699,7 +740,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
699 740
700 i2c_dev->base = base; 741 i2c_dev->base = base;
701 i2c_dev->div_clk = div_clk; 742 i2c_dev->div_clk = div_clk;
702 i2c_dev->fast_clk = fast_clk;
703 i2c_dev->adapter.algo = &tegra_i2c_algo; 743 i2c_dev->adapter.algo = &tegra_i2c_algo;
704 i2c_dev->irq = irq; 744 i2c_dev->irq = irq;
705 i2c_dev->cont_id = pdev->id; 745 i2c_dev->cont_id = pdev->id;
@@ -730,6 +770,15 @@ static int tegra_i2c_probe(struct platform_device *pdev)
730 } 770 }
731 init_completion(&i2c_dev->msg_complete); 771 init_completion(&i2c_dev->msg_complete);
732 772
773 if (!i2c_dev->hw->has_single_clk_source) {
774 fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
775 if (IS_ERR(fast_clk)) {
776 dev_err(&pdev->dev, "missing fast clock");
777 return PTR_ERR(fast_clk);
778 }
779 i2c_dev->fast_clk = fast_clk;
780 }
781
733 platform_set_drvdata(pdev, i2c_dev); 782 platform_set_drvdata(pdev, i2c_dev);
734 783
735 ret = tegra_i2c_init(i2c_dev); 784 ret = tegra_i2c_init(i2c_dev);