aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c135
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h104
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c6
3 files changed, 143 insertions, 102 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index e8b83d9029e1..b9f18ddaaa76 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -34,6 +34,108 @@
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include "i2c-designware-core.h" 35#include "i2c-designware-core.h"
36 36
37/*
38 * Registers offset
39 */
40#define DW_IC_CON 0x0
41#define DW_IC_TAR 0x4
42#define DW_IC_DATA_CMD 0x10
43#define DW_IC_SS_SCL_HCNT 0x14
44#define DW_IC_SS_SCL_LCNT 0x18
45#define DW_IC_FS_SCL_HCNT 0x1c
46#define DW_IC_FS_SCL_LCNT 0x20
47#define DW_IC_INTR_STAT 0x2c
48#define DW_IC_INTR_MASK 0x30
49#define DW_IC_RAW_INTR_STAT 0x34
50#define DW_IC_RX_TL 0x38
51#define DW_IC_TX_TL 0x3c
52#define DW_IC_CLR_INTR 0x40
53#define DW_IC_CLR_RX_UNDER 0x44
54#define DW_IC_CLR_RX_OVER 0x48
55#define DW_IC_CLR_TX_OVER 0x4c
56#define DW_IC_CLR_RD_REQ 0x50
57#define DW_IC_CLR_TX_ABRT 0x54
58#define DW_IC_CLR_RX_DONE 0x58
59#define DW_IC_CLR_ACTIVITY 0x5c
60#define DW_IC_CLR_STOP_DET 0x60
61#define DW_IC_CLR_START_DET 0x64
62#define DW_IC_CLR_GEN_CALL 0x68
63#define DW_IC_ENABLE 0x6c
64#define DW_IC_STATUS 0x70
65#define DW_IC_TXFLR 0x74
66#define DW_IC_RXFLR 0x78
67#define DW_IC_TX_ABRT_SOURCE 0x80
68#define DW_IC_COMP_PARAM_1 0xf4
69#define DW_IC_COMP_TYPE 0xfc
70#define DW_IC_COMP_TYPE_VALUE 0x44570140
71
72#define DW_IC_INTR_RX_UNDER 0x001
73#define DW_IC_INTR_RX_OVER 0x002
74#define DW_IC_INTR_RX_FULL 0x004
75#define DW_IC_INTR_TX_OVER 0x008
76#define DW_IC_INTR_TX_EMPTY 0x010
77#define DW_IC_INTR_RD_REQ 0x020
78#define DW_IC_INTR_TX_ABRT 0x040
79#define DW_IC_INTR_RX_DONE 0x080
80#define DW_IC_INTR_ACTIVITY 0x100
81#define DW_IC_INTR_STOP_DET 0x200
82#define DW_IC_INTR_START_DET 0x400
83#define DW_IC_INTR_GEN_CALL 0x800
84
85#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
86 DW_IC_INTR_TX_EMPTY | \
87 DW_IC_INTR_TX_ABRT | \
88 DW_IC_INTR_STOP_DET)
89
90#define DW_IC_STATUS_ACTIVITY 0x1
91
92#define DW_IC_ERR_TX_ABRT 0x1
93
94/*
95 * status codes
96 */
97#define STATUS_IDLE 0x0
98#define STATUS_WRITE_IN_PROGRESS 0x1
99#define STATUS_READ_IN_PROGRESS 0x2
100
101#define TIMEOUT 20 /* ms */
102
103/*
104 * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
105 *
106 * only expected abort codes are listed here
107 * refer to the datasheet for the full list
108 */
109#define ABRT_7B_ADDR_NOACK 0
110#define ABRT_10ADDR1_NOACK 1
111#define ABRT_10ADDR2_NOACK 2
112#define ABRT_TXDATA_NOACK 3
113#define ABRT_GCALL_NOACK 4
114#define ABRT_GCALL_READ 5
115#define ABRT_SBYTE_ACKDET 7
116#define ABRT_SBYTE_NORSTRT 9
117#define ABRT_10B_RD_NORSTRT 10
118#define ABRT_MASTER_DIS 11
119#define ARB_LOST 12
120
121#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
122#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
123#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
124#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
125#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
126#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
127#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
128#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
129#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
130#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
131#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
132
133#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
134 DW_IC_TX_ABRT_10ADDR1_NOACK | \
135 DW_IC_TX_ABRT_10ADDR2_NOACK | \
136 DW_IC_TX_ABRT_TXDATA_NOACK | \
137 DW_IC_TX_ABRT_GCALL_NOACK)
138
37static char *abort_sources[] = { 139static char *abort_sources[] = {
38 [ABRT_7B_ADDR_NOACK] = 140 [ABRT_7B_ADDR_NOACK] =
39 "slave address not acknowledged (7bit mode)", 141 "slave address not acknowledged (7bit mode)",
@@ -562,3 +664,36 @@ tx_aborted:
562 664
563 return IRQ_HANDLED; 665 return IRQ_HANDLED;
564} 666}
667
668void i2c_dw_enable(struct dw_i2c_dev *dev)
669{
670 /* Enable the adapter */
671 dw_writel(dev, 1, DW_IC_ENABLE);
672}
673
674void i2c_dw_disable(struct dw_i2c_dev *dev)
675{
676 int ret;
677
678 /* Disable controller */
679 dw_writel(dev, 0, DW_IC_ENABLE);
680
681 /* Disable all interupts */
682 dw_writel(dev, 0, DW_IC_INTR_MASK);
683 dw_readl(dev, DW_IC_CLR_INTR);
684}
685
686void i2c_dw_clear_int(struct dw_i2c_dev *dev)
687{
688 dw_readl(dev, DW_IC_CLR_INTR);
689}
690
691void i2c_dw_disable_int(struct dw_i2c_dev *dev)
692{
693 dw_writel(dev, 0, DW_IC_INTR_MASK);
694}
695
696u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)
697{
698 return dw_readl(dev, DW_IC_COMP_PARAM_1);
699}
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 29386215fe3c..dc016e2afe9c 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -26,40 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29/*
30 * Registers offset
31 */
32#define DW_IC_CON 0x0
33#define DW_IC_TAR 0x4
34#define DW_IC_DATA_CMD 0x10
35#define DW_IC_SS_SCL_HCNT 0x14
36#define DW_IC_SS_SCL_LCNT 0x18
37#define DW_IC_FS_SCL_HCNT 0x1c
38#define DW_IC_FS_SCL_LCNT 0x20
39#define DW_IC_INTR_STAT 0x2c
40#define DW_IC_INTR_MASK 0x30
41#define DW_IC_RAW_INTR_STAT 0x34
42#define DW_IC_RX_TL 0x38
43#define DW_IC_TX_TL 0x3c
44#define DW_IC_CLR_INTR 0x40
45#define DW_IC_CLR_RX_UNDER 0x44
46#define DW_IC_CLR_RX_OVER 0x48
47#define DW_IC_CLR_TX_OVER 0x4c
48#define DW_IC_CLR_RD_REQ 0x50
49#define DW_IC_CLR_TX_ABRT 0x54
50#define DW_IC_CLR_RX_DONE 0x58
51#define DW_IC_CLR_ACTIVITY 0x5c
52#define DW_IC_CLR_STOP_DET 0x60
53#define DW_IC_CLR_START_DET 0x64
54#define DW_IC_CLR_GEN_CALL 0x68
55#define DW_IC_ENABLE 0x6c
56#define DW_IC_STATUS 0x70
57#define DW_IC_TXFLR 0x74
58#define DW_IC_RXFLR 0x78
59#define DW_IC_TX_ABRT_SOURCE 0x80
60#define DW_IC_COMP_PARAM_1 0xf4
61#define DW_IC_COMP_TYPE 0xfc
62#define DW_IC_COMP_TYPE_VALUE 0x44570140
63 29
64#define DW_IC_CON_MASTER 0x1 30#define DW_IC_CON_MASTER 0x1
65#define DW_IC_CON_SPEED_STD 0x2 31#define DW_IC_CON_SPEED_STD 0x2
@@ -68,72 +34,7 @@
68#define DW_IC_CON_RESTART_EN 0x20 34#define DW_IC_CON_RESTART_EN 0x20
69#define DW_IC_CON_SLAVE_DISABLE 0x40 35#define DW_IC_CON_SLAVE_DISABLE 0x40
70 36
71#define DW_IC_INTR_RX_UNDER 0x001
72#define DW_IC_INTR_RX_OVER 0x002
73#define DW_IC_INTR_RX_FULL 0x004
74#define DW_IC_INTR_TX_OVER 0x008
75#define DW_IC_INTR_TX_EMPTY 0x010
76#define DW_IC_INTR_RD_REQ 0x020
77#define DW_IC_INTR_TX_ABRT 0x040
78#define DW_IC_INTR_RX_DONE 0x080
79#define DW_IC_INTR_ACTIVITY 0x100
80#define DW_IC_INTR_STOP_DET 0x200
81#define DW_IC_INTR_START_DET 0x400
82#define DW_IC_INTR_GEN_CALL 0x800
83
84#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
85 DW_IC_INTR_TX_EMPTY | \
86 DW_IC_INTR_TX_ABRT | \
87 DW_IC_INTR_STOP_DET)
88
89#define DW_IC_STATUS_ACTIVITY 0x1
90
91#define DW_IC_ERR_TX_ABRT 0x1
92
93/*
94 * status codes
95 */
96#define STATUS_IDLE 0x0
97#define STATUS_WRITE_IN_PROGRESS 0x1
98#define STATUS_READ_IN_PROGRESS 0x2
99
100#define TIMEOUT 20 /* ms */
101
102/*
103 * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
104 *
105 * only expected abort codes are listed here
106 * refer to the datasheet for the full list
107 */
108#define ABRT_7B_ADDR_NOACK 0
109#define ABRT_10ADDR1_NOACK 1
110#define ABRT_10ADDR2_NOACK 2
111#define ABRT_TXDATA_NOACK 3
112#define ABRT_GCALL_NOACK 4
113#define ABRT_GCALL_READ 5
114#define ABRT_SBYTE_ACKDET 7
115#define ABRT_SBYTE_NORSTRT 9
116#define ABRT_10B_RD_NORSTRT 10
117#define ABRT_MASTER_DIS 11
118#define ARB_LOST 12
119
120#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
121#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
122#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
123#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
124#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
125#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
126#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
127#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
128#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
129#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
130#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
131 37
132#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
133 DW_IC_TX_ABRT_10ADDR1_NOACK | \
134 DW_IC_TX_ABRT_10ADDR2_NOACK | \
135 DW_IC_TX_ABRT_TXDATA_NOACK | \
136 DW_IC_TX_ABRT_GCALL_NOACK)
137/** 38/**
138 * struct dw_i2c_dev - private i2c-designware data 39 * struct dw_i2c_dev - private i2c-designware data
139 * @dev: driver model device node 40 * @dev: driver model device node
@@ -195,3 +96,8 @@ extern int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
195 int num); 96 int num);
196extern u32 i2c_dw_func(struct i2c_adapter *adap); 97extern u32 i2c_dw_func(struct i2c_adapter *adap);
197extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id); 98extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id);
99extern void i2c_dw_enable(struct dw_i2c_dev *dev);
100extern void i2c_dw_disable(struct dw_i2c_dev *dev);
101extern void i2c_dw_clear_int(struct dw_i2c_dev *dev);
102extern void i2c_dw_disable_int(struct dw_i2c_dev *dev);
103extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 1258cae3555d..2d3657ab1258 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -113,7 +113,7 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev)
113 goto err_unuse_clocks; 113 goto err_unuse_clocks;
114 } 114 }
115 { 115 {
116 u32 param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); 116 u32 param1 = i2c_dw_read_comp_param(dev);
117 117
118 dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1; 118 dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
119 dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1; 119 dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
@@ -122,7 +122,7 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev)
122 if (r) 122 if (r)
123 goto err_iounmap; 123 goto err_iounmap;
124 124
125 dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */ 125 i2c_dw_disable_int(dev);
126 r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev); 126 r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
127 if (r) { 127 if (r) {
128 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); 128 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
@@ -178,7 +178,7 @@ static int __devexit dw_i2c_remove(struct platform_device *pdev)
178 clk_put(dev->clk); 178 clk_put(dev->clk);
179 dev->clk = NULL; 179 dev->clk = NULL;
180 180
181 dw_writel(dev, 0, DW_IC_ENABLE); 181 i2c_dw_disable(dev);
182 free_irq(dev->irq, dev); 182 free_irq(dev->irq, dev);
183 kfree(dev); 183 kfree(dev);
184 184