6
6
* I2C master mode controller driver, used in Nomadik 8815
7
7
* and Ux500 platforms.
8
8
*
9
+ * The Mobileye EyeQ5 platform is also supported; it uses
10
+ * the same Ux500/DB8500 IP block with two quirks:
11
+ * - The memory bus only supports 32-bit accesses.
12
+ * - A register must be configured for the I2C speed mode;
13
+ * it is located in a shared register region called OLB.
14
+ *
9
15
* Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
10
16
* Author: Sachin Verma <sachin.verma@st.com>
11
17
*/
22
28
#include <linux/pm_runtime.h>
23
29
#include <linux/of.h>
24
30
#include <linux/pinctrl/consumer.h>
31
+ #include <linux/mfd/syscon.h>
32
+ #include <linux/regmap.h>
25
33
26
34
#define DRIVER_NAME "nmk-i2c"
27
35
@@ -110,6 +118,15 @@ enum i2c_freq_mode {
110
118
I2C_FREQ_MODE_FAST_PLUS , /* up to 1 Mb/s */
111
119
};
112
120
121
+ /* Mobileye EyeQ5 offset into a shared register region (called OLB) */
122
+ #define NMK_I2C_EYEQ5_OLB_IOCR2 0x0B8
123
+
124
+ enum i2c_eyeq5_speed {
125
+ I2C_EYEQ5_SPEED_FAST ,
126
+ I2C_EYEQ5_SPEED_FAST_PLUS ,
127
+ I2C_EYEQ5_SPEED_HIGH_SPEED ,
128
+ };
129
+
113
130
/**
114
131
* struct i2c_vendor_data - per-vendor variations
115
132
* @has_mtdws: variant has the MTDWS bit
@@ -174,6 +191,7 @@ struct i2c_nmk_client {
174
191
* @xfer_wq: xfer done wait queue.
175
192
* @xfer_done: xfer done boolean.
176
193
* @result: controller propogated result.
194
+ * @has_32b_bus: controller is on a bus that only supports 32-bit accesses.
177
195
*/
178
196
struct nmk_i2c_dev {
179
197
struct i2c_vendor_data * vendor ;
@@ -192,6 +210,7 @@ struct nmk_i2c_dev {
192
210
struct wait_queue_head xfer_wq ;
193
211
bool xfer_done ;
194
212
int result ;
213
+ bool has_32b_bus ;
195
214
};
196
215
197
216
/* controller's abort causes */
@@ -215,6 +234,24 @@ static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
215
234
writel (readl (reg ) & ~mask , reg );
216
235
}
217
236
237
+ static inline u8 nmk_i2c_readb (const struct nmk_i2c_dev * priv ,
238
+ unsigned long reg )
239
+ {
240
+ if (priv -> has_32b_bus )
241
+ return readl (priv -> virtbase + reg );
242
+ else
243
+ return readb (priv -> virtbase + reg );
244
+ }
245
+
246
+ static inline void nmk_i2c_writeb (const struct nmk_i2c_dev * priv , u32 val ,
247
+ unsigned long reg )
248
+ {
249
+ if (priv -> has_32b_bus )
250
+ writel (val , priv -> virtbase + reg );
251
+ else
252
+ writeb (val , priv -> virtbase + reg );
253
+ }
254
+
218
255
/**
219
256
* flush_i2c_fifo() - This function flushes the I2C FIFO
220
257
* @priv: private data of I2C Driver
@@ -523,7 +560,7 @@ static void fill_tx_fifo(struct nmk_i2c_dev *priv, int no_bytes)
523
560
(priv -> cli .count != 0 );
524
561
count -- ) {
525
562
/* write to the Tx FIFO */
526
- writeb ( * priv -> cli .buffer , priv -> virtbase + I2C_TFR );
563
+ nmk_i2c_writeb ( priv , * priv -> cli .buffer , I2C_TFR );
527
564
priv -> cli .buffer ++ ;
528
565
priv -> cli .count -- ;
529
566
priv -> cli .xfer_bytes ++ ;
@@ -792,7 +829,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
792
829
case I2C_IT_RXFNF :
793
830
for (count = rft ; count > 0 ; count -- ) {
794
831
/* Read the Rx FIFO */
795
- * priv -> cli .buffer = readb (priv -> virtbase + I2C_RFR );
832
+ * priv -> cli .buffer = nmk_i2c_readb (priv , I2C_RFR );
796
833
priv -> cli .buffer ++ ;
797
834
}
798
835
priv -> cli .count -= rft ;
@@ -802,7 +839,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
802
839
/* Rx FIFO full */
803
840
case I2C_IT_RXFF :
804
841
for (count = MAX_I2C_FIFO_THRESHOLD ; count > 0 ; count -- ) {
805
- * priv -> cli .buffer = readb (priv -> virtbase + I2C_RFR );
842
+ * priv -> cli .buffer = nmk_i2c_readb (priv , I2C_RFR );
806
843
priv -> cli .buffer ++ ;
807
844
}
808
845
priv -> cli .count -= MAX_I2C_FIFO_THRESHOLD ;
@@ -818,7 +855,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
818
855
if (priv -> cli .count == 0 )
819
856
break ;
820
857
* priv -> cli .buffer =
821
- readb (priv -> virtbase + I2C_RFR );
858
+ nmk_i2c_readb (priv , I2C_RFR );
822
859
priv -> cli .buffer ++ ;
823
860
priv -> cli .count -- ;
824
861
priv -> cli .xfer_bytes ++ ;
@@ -996,6 +1033,44 @@ static void nmk_i2c_of_probe(struct device_node *np,
996
1033
priv -> timeout_usecs = 200 * USEC_PER_MSEC ;
997
1034
}
998
1035
1036
+ static const unsigned int nmk_i2c_eyeq5_masks [] = {
1037
+ GENMASK (5 , 4 ),
1038
+ GENMASK (7 , 6 ),
1039
+ GENMASK (9 , 8 ),
1040
+ GENMASK (11 , 10 ),
1041
+ GENMASK (13 , 12 ),
1042
+ };
1043
+
1044
+ static int nmk_i2c_eyeq5_probe (struct nmk_i2c_dev * priv )
1045
+ {
1046
+ struct device * dev = & priv -> adev -> dev ;
1047
+ struct device_node * np = dev -> of_node ;
1048
+ unsigned int mask , speed_mode ;
1049
+ struct regmap * olb ;
1050
+ unsigned int id ;
1051
+
1052
+ priv -> has_32b_bus = true;
1053
+
1054
+ olb = syscon_regmap_lookup_by_phandle_args (np , "mobileye,olb" , 1 , & id );
1055
+ if (IS_ERR (olb ))
1056
+ return PTR_ERR (olb );
1057
+ if (id >= ARRAY_SIZE (nmk_i2c_eyeq5_masks ))
1058
+ return - ENOENT ;
1059
+
1060
+ if (priv -> clk_freq <= 400000 )
1061
+ speed_mode = I2C_EYEQ5_SPEED_FAST ;
1062
+ else if (priv -> clk_freq <= 1000000 )
1063
+ speed_mode = I2C_EYEQ5_SPEED_FAST_PLUS ;
1064
+ else
1065
+ speed_mode = I2C_EYEQ5_SPEED_HIGH_SPEED ;
1066
+
1067
+ mask = nmk_i2c_eyeq5_masks [id ];
1068
+ regmap_update_bits (olb , NMK_I2C_EYEQ5_OLB_IOCR2 ,
1069
+ mask , speed_mode << __fls (mask ));
1070
+
1071
+ return 0 ;
1072
+ }
1073
+
999
1074
static int nmk_i2c_probe (struct amba_device * adev , const struct amba_id * id )
1000
1075
{
1001
1076
int ret = 0 ;
@@ -1012,8 +1087,15 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
1012
1087
1013
1088
priv -> vendor = vendor ;
1014
1089
priv -> adev = adev ;
1090
+ priv -> has_32b_bus = false;
1015
1091
nmk_i2c_of_probe (np , priv );
1016
1092
1093
+ if (of_device_is_compatible (np , "mobileye,eyeq5-i2c" )) {
1094
+ ret = nmk_i2c_eyeq5_probe (priv );
1095
+ if (ret )
1096
+ return dev_err_probe (dev , ret , "failed OLB lookup\n" );
1097
+ }
1098
+
1017
1099
if (priv -> tft > max_fifo_threshold ) {
1018
1100
dev_warn (dev , "requested TX FIFO threshold %u, adjusted down to %u\n" ,
1019
1101
priv -> tft , max_fifo_threshold );
0 commit comments