11/*
2+ * Copyright (C) 2018 Renesas Electronics
3+ *
24 * Copyright (C) 2016 Atmel
35 * Bo Shen <voice.shen@atmel.com>
46 *
2123 */
2224
2325#include <linux/gpio/consumer.h>
26+ #include <linux/i2c-mux.h>
2427#include <linux/i2c.h>
2528#include <linux/module.h>
2629#include <linux/regmap.h>
@@ -86,8 +89,49 @@ struct sii902x {
8689 struct drm_bridge bridge ;
8790 struct drm_connector connector ;
8891 struct gpio_desc * reset_gpio ;
92+ struct i2c_mux_core * i2cmux ;
8993};
9094
95+ static int sii902x_read_unlocked (struct i2c_client * i2c , u8 reg , u8 * val )
96+ {
97+ union i2c_smbus_data data ;
98+ int ret ;
99+
100+ ret = __i2c_smbus_xfer (i2c -> adapter , i2c -> addr , i2c -> flags ,
101+ I2C_SMBUS_READ , reg , I2C_SMBUS_BYTE_DATA , & data );
102+
103+ if (ret < 0 )
104+ return ret ;
105+
106+ * val = data .byte ;
107+ return 0 ;
108+ }
109+
110+ static int sii902x_write_unlocked (struct i2c_client * i2c , u8 reg , u8 val )
111+ {
112+ union i2c_smbus_data data ;
113+
114+ data .byte = val ;
115+
116+ return __i2c_smbus_xfer (i2c -> adapter , i2c -> addr , i2c -> flags ,
117+ I2C_SMBUS_WRITE , reg , I2C_SMBUS_BYTE_DATA ,
118+ & data );
119+ }
120+
121+ static int sii902x_update_bits_unlocked (struct i2c_client * i2c , u8 reg , u8 mask ,
122+ u8 val )
123+ {
124+ int ret ;
125+ u8 status ;
126+
127+ ret = sii902x_read_unlocked (i2c , reg , & status );
128+ if (ret )
129+ return ret ;
130+ status &= ~mask ;
131+ status |= val & mask ;
132+ return sii902x_write_unlocked (i2c , reg , status );
133+ }
134+
91135static inline struct sii902x * bridge_to_sii902x (struct drm_bridge * bridge )
92136{
93137 return container_of (bridge , struct sii902x , bridge );
@@ -135,41 +179,11 @@ static const struct drm_connector_funcs sii902x_connector_funcs = {
135179static int sii902x_get_modes (struct drm_connector * connector )
136180{
137181 struct sii902x * sii902x = connector_to_sii902x (connector );
138- struct regmap * regmap = sii902x -> regmap ;
139182 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24 ;
140- struct device * dev = & sii902x -> i2c -> dev ;
141- unsigned long timeout ;
142- unsigned int retries ;
143- unsigned int status ;
144183 struct edid * edid ;
145- int num = 0 ;
146- int ret ;
147-
148- ret = regmap_update_bits (regmap , SII902X_SYS_CTRL_DATA ,
149- SII902X_SYS_CTRL_DDC_BUS_REQ ,
150- SII902X_SYS_CTRL_DDC_BUS_REQ );
151- if (ret )
152- return ret ;
153-
154- timeout = jiffies +
155- msecs_to_jiffies (SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS );
156- do {
157- ret = regmap_read (regmap , SII902X_SYS_CTRL_DATA , & status );
158- if (ret )
159- return ret ;
160- } while (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD ) &&
161- time_before (jiffies , timeout ));
184+ int num = 0 , ret ;
162185
163- if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD )) {
164- dev_err (dev , "failed to acquire the i2c bus\n" );
165- return - ETIMEDOUT ;
166- }
167-
168- ret = regmap_write (regmap , SII902X_SYS_CTRL_DATA , status );
169- if (ret )
170- return ret ;
171-
172- edid = drm_get_edid (connector , sii902x -> i2c -> adapter );
186+ edid = drm_get_edid (connector , sii902x -> i2cmux -> adapter [0 ]);
173187 drm_connector_update_edid_property (connector , edid );
174188 if (edid ) {
175189 num = drm_add_edid_modes (connector , edid );
@@ -181,42 +195,6 @@ static int sii902x_get_modes(struct drm_connector *connector)
181195 if (ret )
182196 return ret ;
183197
184- /*
185- * Sometimes the I2C bus can stall after failure to use the
186- * EDID channel. Retry a few times to see if things clear
187- * up, else continue anyway.
188- */
189- retries = 5 ;
190- do {
191- ret = regmap_read (regmap , SII902X_SYS_CTRL_DATA ,
192- & status );
193- retries -- ;
194- } while (ret && retries );
195- if (ret )
196- dev_err (dev , "failed to read status (%d)\n" , ret );
197-
198- ret = regmap_update_bits (regmap , SII902X_SYS_CTRL_DATA ,
199- SII902X_SYS_CTRL_DDC_BUS_REQ |
200- SII902X_SYS_CTRL_DDC_BUS_GRTD , 0 );
201- if (ret )
202- return ret ;
203-
204- timeout = jiffies +
205- msecs_to_jiffies (SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS );
206- do {
207- ret = regmap_read (regmap , SII902X_SYS_CTRL_DATA , & status );
208- if (ret )
209- return ret ;
210- } while (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
211- SII902X_SYS_CTRL_DDC_BUS_GRTD ) &&
212- time_before (jiffies , timeout ));
213-
214- if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
215- SII902X_SYS_CTRL_DDC_BUS_GRTD )) {
216- dev_err (dev , "failed to release the i2c bus\n" );
217- return - ETIMEDOUT ;
218- }
219-
220198 return num ;
221199}
222200
@@ -366,6 +344,121 @@ static irqreturn_t sii902x_interrupt(int irq, void *data)
366344 return IRQ_HANDLED ;
367345}
368346
347+ /*
348+ * The purpose of sii902x_i2c_bypass_select is to enable the pass through
349+ * mode of the HDMI transmitter. Do not use regmap from within this function,
350+ * only use sii902x_*_unlocked functions to read/modify/write registers.
351+ * We are holding the parent adapter lock here, keep this in mind before
352+ * adding more i2c transactions.
353+ *
354+ * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
355+ * in this driver, we need to make sure that we only touch 0x1A[2:1] from
356+ * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
357+ * we leave the remaining bits as we have found them.
358+ */
359+ static int sii902x_i2c_bypass_select (struct i2c_mux_core * mux , u32 chan_id )
360+ {
361+ struct sii902x * sii902x = i2c_mux_priv (mux );
362+ struct device * dev = & sii902x -> i2c -> dev ;
363+ unsigned long timeout ;
364+ u8 status ;
365+ int ret ;
366+
367+ ret = sii902x_update_bits_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
368+ SII902X_SYS_CTRL_DDC_BUS_REQ ,
369+ SII902X_SYS_CTRL_DDC_BUS_REQ );
370+ if (ret )
371+ return ret ;
372+
373+ timeout = jiffies +
374+ msecs_to_jiffies (SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS );
375+ do {
376+ ret = sii902x_read_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
377+ & status );
378+ if (ret )
379+ return ret ;
380+ } while (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD ) &&
381+ time_before (jiffies , timeout ));
382+
383+ if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD )) {
384+ dev_err (dev , "Failed to acquire the i2c bus\n" );
385+ return - ETIMEDOUT ;
386+ }
387+
388+ return sii902x_write_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
389+ status );
390+ }
391+
392+ /*
393+ * The purpose of sii902x_i2c_bypass_deselect is to disable the pass through
394+ * mode of the HDMI transmitter. Do not use regmap from within this function,
395+ * only use sii902x_*_unlocked functions to read/modify/write registers.
396+ * We are holding the parent adapter lock here, keep this in mind before
397+ * adding more i2c transactions.
398+ *
399+ * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
400+ * in this driver, we need to make sure that we only touch 0x1A[2:1] from
401+ * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
402+ * we leave the remaining bits as we have found them.
403+ */
404+ static int sii902x_i2c_bypass_deselect (struct i2c_mux_core * mux , u32 chan_id )
405+ {
406+ struct sii902x * sii902x = i2c_mux_priv (mux );
407+ struct device * dev = & sii902x -> i2c -> dev ;
408+ unsigned long timeout ;
409+ unsigned int retries ;
410+ u8 status ;
411+ int ret ;
412+
413+ /*
414+ * When the HDMI transmitter is in pass through mode, we need an
415+ * (undocumented) additional delay between STOP and START conditions
416+ * to guarantee the bus won't get stuck.
417+ */
418+ udelay (30 );
419+
420+ /*
421+ * Sometimes the I2C bus can stall after failure to use the
422+ * EDID channel. Retry a few times to see if things clear
423+ * up, else continue anyway.
424+ */
425+ retries = 5 ;
426+ do {
427+ ret = sii902x_read_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
428+ & status );
429+ retries -- ;
430+ } while (ret && retries );
431+ if (ret ) {
432+ dev_err (dev , "failed to read status (%d)\n" , ret );
433+ return ret ;
434+ }
435+
436+ ret = sii902x_update_bits_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
437+ SII902X_SYS_CTRL_DDC_BUS_REQ |
438+ SII902X_SYS_CTRL_DDC_BUS_GRTD , 0 );
439+ if (ret )
440+ return ret ;
441+
442+ timeout = jiffies +
443+ msecs_to_jiffies (SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS );
444+ do {
445+ ret = sii902x_read_unlocked (sii902x -> i2c , SII902X_SYS_CTRL_DATA ,
446+ & status );
447+ if (ret )
448+ return ret ;
449+ } while (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
450+ SII902X_SYS_CTRL_DDC_BUS_GRTD ) &&
451+ time_before (jiffies , timeout ));
452+
453+ if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
454+ SII902X_SYS_CTRL_DDC_BUS_GRTD )) {
455+ dev_err (dev , "failed to release the i2c bus\n" );
456+ return - ETIMEDOUT ;
457+ }
458+
459+ return 0 ;
460+ }
461+
369462static int sii902x_probe (struct i2c_client * client ,
370463 const struct i2c_device_id * id )
371464{
@@ -375,6 +468,13 @@ static int sii902x_probe(struct i2c_client *client,
375468 u8 chipid [4 ];
376469 int ret ;
377470
471+ ret = i2c_check_functionality (client -> adapter ,
472+ I2C_FUNC_SMBUS_BYTE_DATA );
473+ if (!ret ) {
474+ dev_err (dev , "I2C adapter not suitable\n" );
475+ return - EIO ;
476+ }
477+
378478 sii902x = devm_kzalloc (dev , sizeof (* sii902x ), GFP_KERNEL );
379479 if (!sii902x )
380480 return - ENOMEM ;
@@ -433,14 +533,23 @@ static int sii902x_probe(struct i2c_client *client,
433533
434534 i2c_set_clientdata (client , sii902x );
435535
436- return 0 ;
536+ sii902x -> i2cmux = i2c_mux_alloc (client -> adapter , dev ,
537+ 1 , 0 , I2C_MUX_GATE ,
538+ sii902x_i2c_bypass_select ,
539+ sii902x_i2c_bypass_deselect );
540+ if (!sii902x -> i2cmux )
541+ return - ENOMEM ;
542+
543+ sii902x -> i2cmux -> priv = sii902x ;
544+ return i2c_mux_add_adapter (sii902x -> i2cmux , 0 , 0 , 0 );
437545}
438546
439547static int sii902x_remove (struct i2c_client * client )
440548
441549{
442550 struct sii902x * sii902x = i2c_get_clientdata (client );
443551
552+ i2c_mux_del_adapters (sii902x -> i2cmux );
444553 drm_bridge_remove (& sii902x -> bridge );
445554
446555 return 0 ;
0 commit comments