88
99#include <linux/device.h>
1010#include <linux/gpio/consumer.h>
11- #include <linux/i2c.h>
1211#include <linux/module.h>
13- #include <linux/regmap .h>
12+ #include <linux/of_device .h>
1413#include <linux/slab.h>
1514
1615#include <drm/drmP.h>
1716#include <drm/drm_atomic.h>
1817#include <drm/drm_atomic_helper.h>
19- #include <drm/drm_crtc_helper.h>
2018#include <drm/drm_edid.h>
2119
2220#include "adv7511.h"
2321
24- struct adv7511 {
25- struct i2c_client * i2c_main ;
26- struct i2c_client * i2c_edid ;
27-
28- struct regmap * regmap ;
29- struct regmap * packet_memory_regmap ;
30- enum drm_connector_status status ;
31- bool powered ;
32-
33- unsigned int f_tmds ;
34-
35- unsigned int current_edid_segment ;
36- uint8_t edid_buf [256 ];
37- bool edid_read ;
38-
39- wait_queue_head_t wq ;
40- struct drm_bridge bridge ;
41- struct drm_connector connector ;
42-
43- bool embedded_sync ;
44- enum adv7511_sync_polarity vsync_polarity ;
45- enum adv7511_sync_polarity hsync_polarity ;
46- bool rgb ;
47-
48- struct edid * edid ;
49-
50- struct gpio_desc * gpio_pd ;
51- };
52-
5322/* ADI recommended values for proper operation. */
5423static const struct reg_sequence adv7511_fixed_registers [] = {
5524 { 0x98 , 0x03 },
@@ -391,6 +360,9 @@ static void adv7511_power_on(struct adv7511 *adv7511)
391360 */
392361 regcache_sync (adv7511 -> regmap );
393362
363+ if (adv7511 -> type == ADV7533 )
364+ adv7533_dsi_power_on (adv7511 );
365+
394366 adv7511 -> powered = true;
395367}
396368
@@ -402,6 +374,9 @@ static void adv7511_power_off(struct adv7511 *adv7511)
402374 ADV7511_POWER_POWER_DOWN );
403375 regcache_mark_dirty (adv7511 -> regmap );
404376
377+ if (adv7511 -> type == ADV7533 )
378+ adv7533_dsi_power_off (adv7511 );
379+
405380 adv7511 -> powered = false;
406381}
407382
@@ -862,8 +837,6 @@ static int adv7511_parse_dt(struct device_node *np,
862837 const char * str ;
863838 int ret ;
864839
865- memset (config , 0 , sizeof (* config ));
866-
867840 of_property_read_u32 (np , "adi,input-depth" , & config -> input_color_depth );
868841 if (config -> input_color_depth != 8 && config -> input_color_depth != 10 &&
869842 config -> input_color_depth != 12 )
@@ -963,9 +936,18 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
963936 adv7511 -> powered = false;
964937 adv7511 -> status = connector_status_disconnected ;
965938
966- ret = adv7511_parse_dt (dev -> of_node , & link_config );
967- if (ret )
968- return ret ;
939+ if (dev -> of_node )
940+ adv7511 -> type = (enum adv7511_type )of_device_get_match_data (dev );
941+ else
942+ adv7511 -> type = id -> driver_data ;
943+
944+ memset (& link_config , 0 , sizeof (link_config ));
945+
946+ if (adv7511 -> type == ADV7511 ) {
947+ ret = adv7511_parse_dt (dev -> of_node , & link_config );
948+ if (ret )
949+ return ret ;
950+ }
969951
970952 /*
971953 * The power down GPIO is optional. If present, toggle it from active to
@@ -989,8 +971,12 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
989971 return ret ;
990972 dev_dbg (dev , "Rev. %d\n" , val );
991973
992- ret = regmap_register_patch (adv7511 -> regmap , adv7511_fixed_registers ,
993- ARRAY_SIZE (adv7511_fixed_registers ));
974+ if (adv7511 -> type == ADV7511 )
975+ ret = regmap_register_patch (adv7511 -> regmap ,
976+ adv7511_fixed_registers ,
977+ ARRAY_SIZE (adv7511_fixed_registers ));
978+ else
979+ ret = adv7533_patch_registers (adv7511 );
994980 if (ret )
995981 return ret ;
996982
@@ -1005,6 +991,12 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
1005991 if (!adv7511 -> i2c_edid )
1006992 return - ENOMEM ;
1007993
994+ if (adv7511 -> type == ADV7533 ) {
995+ ret = adv7533_init_cec (adv7511 );
996+ if (ret )
997+ goto err_i2c_unregister_edid ;
998+ }
999+
10081000 if (i2c -> irq ) {
10091001 init_waitqueue_head (& adv7511 -> wq );
10101002
@@ -1013,7 +1005,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
10131005 IRQF_ONESHOT , dev_name (dev ),
10141006 adv7511 );
10151007 if (ret )
1016- goto err_i2c_unregister_device ;
1008+ goto err_unregister_cec ;
10171009 }
10181010
10191011 /* CEC is unused for now */
@@ -1024,20 +1016,23 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
10241016
10251017 i2c_set_clientdata (i2c , adv7511 );
10261018
1027- adv7511_set_link_config (adv7511 , & link_config );
1019+ if (adv7511 -> type == ADV7511 )
1020+ adv7511_set_link_config (adv7511 , & link_config );
10281021
10291022 adv7511 -> bridge .funcs = & adv7511_bridge_funcs ;
10301023 adv7511 -> bridge .of_node = dev -> of_node ;
10311024
10321025 ret = drm_bridge_add (& adv7511 -> bridge );
10331026 if (ret ) {
10341027 dev_err (dev , "failed to add adv7511 bridge\n" );
1035- goto err_i2c_unregister_device ;
1028+ goto err_unregister_cec ;
10361029 }
10371030
10381031 return 0 ;
10391032
1040- err_i2c_unregister_device :
1033+ err_unregister_cec :
1034+ adv7533_uninit_cec (adv7511 );
1035+ err_i2c_unregister_edid :
10411036 i2c_unregister_device (adv7511 -> i2c_edid );
10421037
10431038 return ret ;
@@ -1049,6 +1044,7 @@ static int adv7511_remove(struct i2c_client *i2c)
10491044
10501045 drm_bridge_remove (& adv7511 -> bridge );
10511046
1047+ adv7533_uninit_cec (adv7511 );
10521048 i2c_unregister_device (adv7511 -> i2c_edid );
10531049
10541050 kfree (adv7511 -> edid );
@@ -1057,17 +1053,23 @@ static int adv7511_remove(struct i2c_client *i2c)
10571053}
10581054
10591055static const struct i2c_device_id adv7511_i2c_ids [] = {
1060- { "adv7511" , 0 },
1061- { "adv7511w" , 0 },
1062- { "adv7513" , 0 },
1056+ { "adv7511" , ADV7511 },
1057+ { "adv7511w" , ADV7511 },
1058+ { "adv7513" , ADV7511 },
1059+ #ifdef CONFIG_DRM_I2C_ADV7533
1060+ { "adv7533" , ADV7533 },
1061+ #endif
10631062 { }
10641063};
10651064MODULE_DEVICE_TABLE (i2c , adv7511_i2c_ids );
10661065
10671066static const struct of_device_id adv7511_of_ids [] = {
1068- { .compatible = "adi,adv7511" , },
1069- { .compatible = "adi,adv7511w" , },
1070- { .compatible = "adi,adv7513" , },
1067+ { .compatible = "adi,adv7511" , .data = (void * )ADV7511 },
1068+ { .compatible = "adi,adv7511w" , .data = (void * )ADV7511 },
1069+ { .compatible = "adi,adv7513" , .data = (void * )ADV7511 },
1070+ #ifdef CONFIG_DRM_I2C_ADV7533
1071+ { .compatible = "adi,adv7533" , .data = (void * )ADV7533 },
1072+ #endif
10711073 { }
10721074};
10731075MODULE_DEVICE_TABLE (of , adv7511_of_ids );
0 commit comments