diff options
-rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 650293ff4d62..9f1423ac7b3b 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -106,6 +106,16 @@ | |||
106 | /* maximum threshold value */ | 106 | /* maximum threshold value */ |
107 | #define MAX_I2C_FIFO_THRESHOLD 15 | 107 | #define MAX_I2C_FIFO_THRESHOLD 15 |
108 | 108 | ||
109 | /** | ||
110 | * struct i2c_vendor_data - per-vendor variations | ||
111 | * @has_mtdws: variant has the MTDWS bit | ||
112 | * @fifodepth: variant FIFO depth | ||
113 | */ | ||
114 | struct i2c_vendor_data { | ||
115 | bool has_mtdws; | ||
116 | u32 fifodepth; | ||
117 | }; | ||
118 | |||
109 | enum i2c_status { | 119 | enum i2c_status { |
110 | I2C_NOP, | 120 | I2C_NOP, |
111 | I2C_ON_GOING, | 121 | I2C_ON_GOING, |
@@ -138,6 +148,7 @@ struct i2c_nmk_client { | |||
138 | 148 | ||
139 | /** | 149 | /** |
140 | * struct nmk_i2c_dev - private data structure of the controller. | 150 | * struct nmk_i2c_dev - private data structure of the controller. |
151 | * @vendor: vendor data for this variant. | ||
141 | * @adev: parent amba device. | 152 | * @adev: parent amba device. |
142 | * @adap: corresponding I2C adapter. | 153 | * @adap: corresponding I2C adapter. |
143 | * @irq: interrupt line for the controller. | 154 | * @irq: interrupt line for the controller. |
@@ -155,6 +166,7 @@ struct i2c_nmk_client { | |||
155 | * @busy: Busy doing transfer. | 166 | * @busy: Busy doing transfer. |
156 | */ | 167 | */ |
157 | struct nmk_i2c_dev { | 168 | struct nmk_i2c_dev { |
169 | struct i2c_vendor_data *vendor; | ||
158 | struct amba_device *adev; | 170 | struct amba_device *adev; |
159 | struct i2c_adapter adap; | 171 | struct i2c_adapter adap; |
160 | int irq; | 172 | int irq; |
@@ -431,7 +443,7 @@ static int read_i2c(struct nmk_i2c_dev *dev, u16 flags) | |||
431 | irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF | | 443 | irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF | |
432 | I2C_IT_MAL | I2C_IT_BERR); | 444 | I2C_IT_MAL | I2C_IT_BERR); |
433 | 445 | ||
434 | if (dev->stop) | 446 | if (dev->stop || !dev->vendor->has_mtdws) |
435 | irq_mask |= I2C_IT_MTD; | 447 | irq_mask |= I2C_IT_MTD; |
436 | else | 448 | else |
437 | irq_mask |= I2C_IT_MTDWS; | 449 | irq_mask |= I2C_IT_MTDWS; |
@@ -511,7 +523,7 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags) | |||
511 | * set the MTDWS bit (Master Transaction Done Without Stop) | 523 | * set the MTDWS bit (Master Transaction Done Without Stop) |
512 | * to start repeated start operation | 524 | * to start repeated start operation |
513 | */ | 525 | */ |
514 | if (dev->stop) | 526 | if (dev->stop || !dev->vendor->has_mtdws) |
515 | irq_mask |= I2C_IT_MTD; | 527 | irq_mask |= I2C_IT_MTD; |
516 | else | 528 | else |
517 | irq_mask |= I2C_IT_MTDWS; | 529 | irq_mask |= I2C_IT_MTDWS; |
@@ -978,6 +990,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) | |||
978 | struct device_node *np = adev->dev.of_node; | 990 | struct device_node *np = adev->dev.of_node; |
979 | struct nmk_i2c_dev *dev; | 991 | struct nmk_i2c_dev *dev; |
980 | struct i2c_adapter *adap; | 992 | struct i2c_adapter *adap; |
993 | struct i2c_vendor_data *vendor = id->data; | ||
994 | u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1; | ||
981 | 995 | ||
982 | if (!pdata) { | 996 | if (!pdata) { |
983 | if (np) { | 997 | if (np) { |
@@ -994,12 +1008,25 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) | |||
994 | pdata = &u8500_i2c; | 1008 | pdata = &u8500_i2c; |
995 | } | 1009 | } |
996 | 1010 | ||
1011 | if (pdata->tft > max_fifo_threshold) { | ||
1012 | dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n", | ||
1013 | pdata->tft, max_fifo_threshold); | ||
1014 | pdata->tft = max_fifo_threshold; | ||
1015 | } | ||
1016 | |||
1017 | if (pdata->rft > max_fifo_threshold) { | ||
1018 | dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n", | ||
1019 | pdata->rft, max_fifo_threshold); | ||
1020 | pdata->rft = max_fifo_threshold; | ||
1021 | } | ||
1022 | |||
997 | dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); | 1023 | dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); |
998 | if (!dev) { | 1024 | if (!dev) { |
999 | dev_err(&adev->dev, "cannot allocate memory\n"); | 1025 | dev_err(&adev->dev, "cannot allocate memory\n"); |
1000 | ret = -ENOMEM; | 1026 | ret = -ENOMEM; |
1001 | goto err_no_mem; | 1027 | goto err_no_mem; |
1002 | } | 1028 | } |
1029 | dev->vendor = vendor; | ||
1003 | dev->busy = false; | 1030 | dev->busy = false; |
1004 | dev->adev = adev; | 1031 | dev->adev = adev; |
1005 | amba_set_drvdata(adev, dev); | 1032 | amba_set_drvdata(adev, dev); |
@@ -1134,14 +1161,26 @@ static int nmk_i2c_remove(struct amba_device *adev) | |||
1134 | return 0; | 1161 | return 0; |
1135 | } | 1162 | } |
1136 | 1163 | ||
1164 | static struct i2c_vendor_data vendor_stn8815 = { | ||
1165 | .has_mtdws = false, | ||
1166 | .fifodepth = 16, /* Guessed from TFTR/RFTR = 7 */ | ||
1167 | }; | ||
1168 | |||
1169 | static struct i2c_vendor_data vendor_db8500 = { | ||
1170 | .has_mtdws = true, | ||
1171 | .fifodepth = 32, /* Guessed from TFTR/RFTR = 15 */ | ||
1172 | }; | ||
1173 | |||
1137 | static struct amba_id nmk_i2c_ids[] = { | 1174 | static struct amba_id nmk_i2c_ids[] = { |
1138 | { | 1175 | { |
1139 | .id = 0x00180024, | 1176 | .id = 0x00180024, |
1140 | .mask = 0x00ffffff, | 1177 | .mask = 0x00ffffff, |
1178 | .data = &vendor_stn8815, | ||
1141 | }, | 1179 | }, |
1142 | { | 1180 | { |
1143 | .id = 0x00380024, | 1181 | .id = 0x00380024, |
1144 | .mask = 0x00ffffff, | 1182 | .mask = 0x00ffffff, |
1183 | .data = &vendor_db8500, | ||
1145 | }, | 1184 | }, |
1146 | {}, | 1185 | {}, |
1147 | }; | 1186 | }; |