15d97408eSIcenowy Zheng // SPDX-License-Identifier: GPL-2.0-only 25d97408eSIcenowy Zheng /* 35d97408eSIcenowy Zheng * Copyright(c) 2016, Analogix Semiconductor. 45d97408eSIcenowy Zheng * 55d97408eSIcenowy Zheng * Based on anx7808 driver obtained from chromeos with copyright: 65d97408eSIcenowy Zheng * Copyright(c) 2013, Google Inc. 75d97408eSIcenowy Zheng */ 85d97408eSIcenowy Zheng #include <linux/delay.h> 95d97408eSIcenowy Zheng #include <linux/err.h> 105d97408eSIcenowy Zheng #include <linux/gpio/consumer.h> 115d97408eSIcenowy Zheng #include <linux/i2c.h> 125d97408eSIcenowy Zheng #include <linux/interrupt.h> 135d97408eSIcenowy Zheng #include <linux/kernel.h> 145d97408eSIcenowy Zheng #include <linux/module.h> 155d97408eSIcenowy Zheng #include <linux/of_irq.h> 165d97408eSIcenowy Zheng #include <linux/of_platform.h> 175d97408eSIcenowy Zheng #include <linux/regmap.h> 185d97408eSIcenowy Zheng #include <linux/regulator/consumer.h> 195d97408eSIcenowy Zheng #include <linux/types.h> 205d97408eSIcenowy Zheng 21da68386dSThomas Zimmermann #include <drm/display/drm_dp_helper.h> 225d97408eSIcenowy Zheng #include <drm/drm_atomic_helper.h> 235d97408eSIcenowy Zheng #include <drm/drm_bridge.h> 245d97408eSIcenowy Zheng #include <drm/drm_crtc.h> 255d97408eSIcenowy Zheng #include <drm/drm_edid.h> 265d97408eSIcenowy Zheng #include <drm/drm_print.h> 275d97408eSIcenowy Zheng #include <drm/drm_probe_helper.h> 285d97408eSIcenowy Zheng 295d97408eSIcenowy Zheng #include "analogix-anx78xx.h" 305d97408eSIcenowy Zheng 315d97408eSIcenowy Zheng #define I2C_NUM_ADDRESSES 5 325d97408eSIcenowy Zheng #define I2C_IDX_TX_P0 0 335d97408eSIcenowy Zheng #define I2C_IDX_TX_P1 1 345d97408eSIcenowy Zheng #define I2C_IDX_TX_P2 2 355d97408eSIcenowy Zheng #define I2C_IDX_RX_P0 3 365d97408eSIcenowy Zheng #define I2C_IDX_RX_P1 4 375d97408eSIcenowy Zheng 385d97408eSIcenowy Zheng #define XTAL_CLK 270 /* 27M */ 395d97408eSIcenowy Zheng 405d97408eSIcenowy Zheng static const u8 anx7808_i2c_addresses[] = { 415d97408eSIcenowy Zheng [I2C_IDX_TX_P0] = 0x78, 425d97408eSIcenowy Zheng [I2C_IDX_TX_P1] = 0x7a, 435d97408eSIcenowy Zheng [I2C_IDX_TX_P2] = 0x72, 445d97408eSIcenowy Zheng [I2C_IDX_RX_P0] = 0x7e, 455d97408eSIcenowy Zheng [I2C_IDX_RX_P1] = 0x80, 465d97408eSIcenowy Zheng }; 475d97408eSIcenowy Zheng 485d97408eSIcenowy Zheng static const u8 anx781x_i2c_addresses[] = { 495d97408eSIcenowy Zheng [I2C_IDX_TX_P0] = 0x70, 505d97408eSIcenowy Zheng [I2C_IDX_TX_P1] = 0x7a, 515d97408eSIcenowy Zheng [I2C_IDX_TX_P2] = 0x72, 525d97408eSIcenowy Zheng [I2C_IDX_RX_P0] = 0x7e, 535d97408eSIcenowy Zheng [I2C_IDX_RX_P1] = 0x80, 545d97408eSIcenowy Zheng }; 555d97408eSIcenowy Zheng 565d97408eSIcenowy Zheng struct anx78xx_platform_data { 575d97408eSIcenowy Zheng struct regulator *dvdd10; 585d97408eSIcenowy Zheng struct gpio_desc *gpiod_hpd; 595d97408eSIcenowy Zheng struct gpio_desc *gpiod_pd; 605d97408eSIcenowy Zheng struct gpio_desc *gpiod_reset; 615d97408eSIcenowy Zheng 625d97408eSIcenowy Zheng int hpd_irq; 635d97408eSIcenowy Zheng int intp_irq; 645d97408eSIcenowy Zheng }; 655d97408eSIcenowy Zheng 665d97408eSIcenowy Zheng struct anx78xx { 675d97408eSIcenowy Zheng struct drm_dp_aux aux; 685d97408eSIcenowy Zheng struct drm_bridge bridge; 695d97408eSIcenowy Zheng struct i2c_client *client; 705d97408eSIcenowy Zheng struct edid *edid; 715d97408eSIcenowy Zheng struct drm_connector connector; 725d97408eSIcenowy Zheng struct anx78xx_platform_data pdata; 735d97408eSIcenowy Zheng struct mutex lock; 745d97408eSIcenowy Zheng 755d97408eSIcenowy Zheng /* 765d97408eSIcenowy Zheng * I2C Slave addresses of ANX7814 are mapped as TX_P0, TX_P1, TX_P2, 775d97408eSIcenowy Zheng * RX_P0 and RX_P1. 785d97408eSIcenowy Zheng */ 795d97408eSIcenowy Zheng struct i2c_client *i2c_dummy[I2C_NUM_ADDRESSES]; 805d97408eSIcenowy Zheng struct regmap *map[I2C_NUM_ADDRESSES]; 815d97408eSIcenowy Zheng 825d97408eSIcenowy Zheng u16 chipid; 835d97408eSIcenowy Zheng u8 dpcd[DP_RECEIVER_CAP_SIZE]; 845d97408eSIcenowy Zheng 855d97408eSIcenowy Zheng bool powered; 865d97408eSIcenowy Zheng }; 875d97408eSIcenowy Zheng 885d97408eSIcenowy Zheng static inline struct anx78xx *connector_to_anx78xx(struct drm_connector *c) 895d97408eSIcenowy Zheng { 905d97408eSIcenowy Zheng return container_of(c, struct anx78xx, connector); 915d97408eSIcenowy Zheng } 925d97408eSIcenowy Zheng 935d97408eSIcenowy Zheng static inline struct anx78xx *bridge_to_anx78xx(struct drm_bridge *bridge) 945d97408eSIcenowy Zheng { 955d97408eSIcenowy Zheng return container_of(bridge, struct anx78xx, bridge); 965d97408eSIcenowy Zheng } 975d97408eSIcenowy Zheng 985d97408eSIcenowy Zheng static int anx78xx_set_bits(struct regmap *map, u8 reg, u8 mask) 995d97408eSIcenowy Zheng { 1005d97408eSIcenowy Zheng return regmap_update_bits(map, reg, mask, mask); 1015d97408eSIcenowy Zheng } 1025d97408eSIcenowy Zheng 1035d97408eSIcenowy Zheng static int anx78xx_clear_bits(struct regmap *map, u8 reg, u8 mask) 1045d97408eSIcenowy Zheng { 1055d97408eSIcenowy Zheng return regmap_update_bits(map, reg, mask, 0); 1065d97408eSIcenowy Zheng } 1075d97408eSIcenowy Zheng 1085d97408eSIcenowy Zheng static ssize_t anx78xx_aux_transfer(struct drm_dp_aux *aux, 1095d97408eSIcenowy Zheng struct drm_dp_aux_msg *msg) 1105d97408eSIcenowy Zheng { 1115d97408eSIcenowy Zheng struct anx78xx *anx78xx = container_of(aux, struct anx78xx, aux); 1120712eca9SIcenowy Zheng return anx_dp_aux_transfer(anx78xx->map[I2C_IDX_TX_P0], msg); 1135d97408eSIcenowy Zheng } 1145d97408eSIcenowy Zheng 1155d97408eSIcenowy Zheng static int anx78xx_set_hpd(struct anx78xx *anx78xx) 1165d97408eSIcenowy Zheng { 1175d97408eSIcenowy Zheng int err; 1185d97408eSIcenowy Zheng 1195d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_RX_P0], 1205d97408eSIcenowy Zheng SP_TMDS_CTRL_BASE + 7, SP_PD_RT); 1215d97408eSIcenowy Zheng if (err) 1225d97408eSIcenowy Zheng return err; 1235d97408eSIcenowy Zheng 1245d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL3_REG, 1255d97408eSIcenowy Zheng SP_HPD_OUT); 1265d97408eSIcenowy Zheng if (err) 1275d97408eSIcenowy Zheng return err; 1285d97408eSIcenowy Zheng 1295d97408eSIcenowy Zheng return 0; 1305d97408eSIcenowy Zheng } 1315d97408eSIcenowy Zheng 1325d97408eSIcenowy Zheng static int anx78xx_clear_hpd(struct anx78xx *anx78xx) 1335d97408eSIcenowy Zheng { 1345d97408eSIcenowy Zheng int err; 1355d97408eSIcenowy Zheng 1365d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL3_REG, 1375d97408eSIcenowy Zheng SP_HPD_OUT); 1385d97408eSIcenowy Zheng if (err) 1395d97408eSIcenowy Zheng return err; 1405d97408eSIcenowy Zheng 1415d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], 1425d97408eSIcenowy Zheng SP_TMDS_CTRL_BASE + 7, SP_PD_RT); 1435d97408eSIcenowy Zheng if (err) 1445d97408eSIcenowy Zheng return err; 1455d97408eSIcenowy Zheng 1465d97408eSIcenowy Zheng return 0; 1475d97408eSIcenowy Zheng } 1485d97408eSIcenowy Zheng 1495d97408eSIcenowy Zheng static const struct reg_sequence tmds_phy_initialization[] = { 1505d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 1, 0x90 }, 1515d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 2, 0xa9 }, 1525d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 6, 0x92 }, 1535d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 7, 0x80 }, 1545d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 20, 0xf2 }, 1555d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 22, 0xc4 }, 1565d97408eSIcenowy Zheng { SP_TMDS_CTRL_BASE + 23, 0x18 }, 1575d97408eSIcenowy Zheng }; 1585d97408eSIcenowy Zheng 1595d97408eSIcenowy Zheng static int anx78xx_rx_initialization(struct anx78xx *anx78xx) 1605d97408eSIcenowy Zheng { 1615d97408eSIcenowy Zheng int err; 1625d97408eSIcenowy Zheng 1635d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_RX_P0], SP_HDMI_MUTE_CTRL_REG, 1645d97408eSIcenowy Zheng SP_AUD_MUTE | SP_VID_MUTE); 1655d97408eSIcenowy Zheng if (err) 1665d97408eSIcenowy Zheng return err; 1675d97408eSIcenowy Zheng 1685d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], SP_CHIP_CTRL_REG, 1695d97408eSIcenowy Zheng SP_MAN_HDMI5V_DET | SP_PLLLOCK_CKDT_EN | 1705d97408eSIcenowy Zheng SP_DIGITAL_CKDT_EN); 1715d97408eSIcenowy Zheng if (err) 1725d97408eSIcenowy Zheng return err; 1735d97408eSIcenowy Zheng 1745d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], 1755d97408eSIcenowy Zheng SP_SOFTWARE_RESET1_REG, SP_HDCP_MAN_RST | 1765d97408eSIcenowy Zheng SP_SW_MAN_RST | SP_TMDS_RST | SP_VIDEO_RST); 1775d97408eSIcenowy Zheng if (err) 1785d97408eSIcenowy Zheng return err; 1795d97408eSIcenowy Zheng 1805d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_RX_P0], 1815d97408eSIcenowy Zheng SP_SOFTWARE_RESET1_REG, SP_HDCP_MAN_RST | 1825d97408eSIcenowy Zheng SP_SW_MAN_RST | SP_TMDS_RST | SP_VIDEO_RST); 1835d97408eSIcenowy Zheng if (err) 1845d97408eSIcenowy Zheng return err; 1855d97408eSIcenowy Zheng 1865d97408eSIcenowy Zheng /* Sync detect change, GP set mute */ 1875d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], 1885d97408eSIcenowy Zheng SP_AUD_EXCEPTION_ENABLE_BASE + 1, BIT(5) | 1895d97408eSIcenowy Zheng BIT(6)); 1905d97408eSIcenowy Zheng if (err) 1915d97408eSIcenowy Zheng return err; 1925d97408eSIcenowy Zheng 1935d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], 1945d97408eSIcenowy Zheng SP_AUD_EXCEPTION_ENABLE_BASE + 3, 1955d97408eSIcenowy Zheng SP_AEC_EN21); 1965d97408eSIcenowy Zheng if (err) 1975d97408eSIcenowy Zheng return err; 1985d97408eSIcenowy Zheng 1995d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], SP_AUDVID_CTRL_REG, 2005d97408eSIcenowy Zheng SP_AVC_EN | SP_AAC_OE | SP_AAC_EN); 2015d97408eSIcenowy Zheng if (err) 2025d97408eSIcenowy Zheng return err; 2035d97408eSIcenowy Zheng 2045d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_RX_P0], 2055d97408eSIcenowy Zheng SP_SYSTEM_POWER_DOWN1_REG, SP_PWDN_CTRL); 2065d97408eSIcenowy Zheng if (err) 2075d97408eSIcenowy Zheng return err; 2085d97408eSIcenowy Zheng 2095d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_RX_P0], 2105d97408eSIcenowy Zheng SP_VID_DATA_RANGE_CTRL_REG, SP_R2Y_INPUT_LIMIT); 2115d97408eSIcenowy Zheng if (err) 2125d97408eSIcenowy Zheng return err; 2135d97408eSIcenowy Zheng 2145d97408eSIcenowy Zheng /* Enable DDC stretch */ 2155d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 2165d97408eSIcenowy Zheng SP_DP_EXTRA_I2C_DEV_ADDR_REG, SP_I2C_EXTRA_ADDR); 2175d97408eSIcenowy Zheng if (err) 2185d97408eSIcenowy Zheng return err; 2195d97408eSIcenowy Zheng 2205d97408eSIcenowy Zheng /* TMDS phy initialization */ 2215d97408eSIcenowy Zheng err = regmap_multi_reg_write(anx78xx->map[I2C_IDX_RX_P0], 2225d97408eSIcenowy Zheng tmds_phy_initialization, 2235d97408eSIcenowy Zheng ARRAY_SIZE(tmds_phy_initialization)); 2245d97408eSIcenowy Zheng if (err) 2255d97408eSIcenowy Zheng return err; 2265d97408eSIcenowy Zheng 2275d97408eSIcenowy Zheng err = anx78xx_clear_hpd(anx78xx); 2285d97408eSIcenowy Zheng if (err) 2295d97408eSIcenowy Zheng return err; 2305d97408eSIcenowy Zheng 2315d97408eSIcenowy Zheng return 0; 2325d97408eSIcenowy Zheng } 2335d97408eSIcenowy Zheng 2345d97408eSIcenowy Zheng static const u8 dp_tx_output_precise_tune_bits[20] = { 2355d97408eSIcenowy Zheng 0x01, 0x03, 0x07, 0x7f, 0x71, 0x6b, 0x7f, 2365d97408eSIcenowy Zheng 0x73, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 2375d97408eSIcenowy Zheng 0x0c, 0x42, 0x1e, 0x3e, 0x72, 0x7e, 2385d97408eSIcenowy Zheng }; 2395d97408eSIcenowy Zheng 2405d97408eSIcenowy Zheng static int anx78xx_link_phy_initialization(struct anx78xx *anx78xx) 2415d97408eSIcenowy Zheng { 2425d97408eSIcenowy Zheng int err; 2435d97408eSIcenowy Zheng 2445d97408eSIcenowy Zheng /* 2455d97408eSIcenowy Zheng * REVISIT : It is writing to a RESERVED bits in Analog Control 0 2465d97408eSIcenowy Zheng * register. 2475d97408eSIcenowy Zheng */ 2485d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], SP_ANALOG_CTRL0_REG, 2495d97408eSIcenowy Zheng 0x02); 2505d97408eSIcenowy Zheng if (err) 2515d97408eSIcenowy Zheng return err; 2525d97408eSIcenowy Zheng 2535d97408eSIcenowy Zheng /* 2545d97408eSIcenowy Zheng * Write DP TX output emphasis precise tune bits. 2555d97408eSIcenowy Zheng */ 2565d97408eSIcenowy Zheng err = regmap_bulk_write(anx78xx->map[I2C_IDX_TX_P1], 2575d97408eSIcenowy Zheng SP_DP_TX_LT_CTRL0_REG, 2585d97408eSIcenowy Zheng dp_tx_output_precise_tune_bits, 2595d97408eSIcenowy Zheng ARRAY_SIZE(dp_tx_output_precise_tune_bits)); 2605d97408eSIcenowy Zheng 2615d97408eSIcenowy Zheng if (err) 2625d97408eSIcenowy Zheng return err; 2635d97408eSIcenowy Zheng 2645d97408eSIcenowy Zheng return 0; 2655d97408eSIcenowy Zheng } 2665d97408eSIcenowy Zheng 2675d97408eSIcenowy Zheng static int anx78xx_xtal_clk_sel(struct anx78xx *anx78xx) 2685d97408eSIcenowy Zheng { 2695d97408eSIcenowy Zheng unsigned int value; 2705d97408eSIcenowy Zheng int err; 2715d97408eSIcenowy Zheng 2725d97408eSIcenowy Zheng err = regmap_update_bits(anx78xx->map[I2C_IDX_TX_P2], 2735d97408eSIcenowy Zheng SP_ANALOG_DEBUG2_REG, 2745d97408eSIcenowy Zheng SP_XTAL_FRQ | SP_FORCE_SW_OFF_BYPASS, 2755d97408eSIcenowy Zheng SP_XTAL_FRQ_27M); 2765d97408eSIcenowy Zheng if (err) 2775d97408eSIcenowy Zheng return err; 2785d97408eSIcenowy Zheng 2795d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_DP_AUX_CH_CTRL3_REG, 2805d97408eSIcenowy Zheng XTAL_CLK & SP_WAIT_COUNTER_7_0_MASK); 2815d97408eSIcenowy Zheng if (err) 2825d97408eSIcenowy Zheng return err; 2835d97408eSIcenowy Zheng 2845d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_DP_AUX_CH_CTRL4_REG, 2855d97408eSIcenowy Zheng ((XTAL_CLK & 0xff00) >> 2) | (XTAL_CLK / 10)); 2865d97408eSIcenowy Zheng if (err) 2875d97408eSIcenowy Zheng return err; 2885d97408eSIcenowy Zheng 2895d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 2905d97408eSIcenowy Zheng SP_I2C_GEN_10US_TIMER0_REG, XTAL_CLK & 0xff); 2915d97408eSIcenowy Zheng if (err) 2925d97408eSIcenowy Zheng return err; 2935d97408eSIcenowy Zheng 2945d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 2955d97408eSIcenowy Zheng SP_I2C_GEN_10US_TIMER1_REG, 2965d97408eSIcenowy Zheng (XTAL_CLK & 0xff00) >> 8); 2975d97408eSIcenowy Zheng if (err) 2985d97408eSIcenowy Zheng return err; 2995d97408eSIcenowy Zheng 3005d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_AUX_MISC_CTRL_REG, 3015d97408eSIcenowy Zheng XTAL_CLK / 10 - 1); 3025d97408eSIcenowy Zheng if (err) 3035d97408eSIcenowy Zheng return err; 3045d97408eSIcenowy Zheng 3055d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_RX_P0], 3065d97408eSIcenowy Zheng SP_HDMI_US_TIMER_CTRL_REG, 3075d97408eSIcenowy Zheng &value); 3085d97408eSIcenowy Zheng if (err) 3095d97408eSIcenowy Zheng return err; 3105d97408eSIcenowy Zheng 3115d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_RX_P0], 3125d97408eSIcenowy Zheng SP_HDMI_US_TIMER_CTRL_REG, 3135d97408eSIcenowy Zheng (value & SP_MS_TIMER_MARGIN_10_8_MASK) | 3145d97408eSIcenowy Zheng ((((XTAL_CLK / 10) >> 1) - 2) << 3)); 3155d97408eSIcenowy Zheng if (err) 3165d97408eSIcenowy Zheng return err; 3175d97408eSIcenowy Zheng 3185d97408eSIcenowy Zheng return 0; 3195d97408eSIcenowy Zheng } 3205d97408eSIcenowy Zheng 3215d97408eSIcenowy Zheng static const struct reg_sequence otp_key_protect[] = { 3225d97408eSIcenowy Zheng { SP_OTP_KEY_PROTECT1_REG, SP_OTP_PSW1 }, 3235d97408eSIcenowy Zheng { SP_OTP_KEY_PROTECT2_REG, SP_OTP_PSW2 }, 3245d97408eSIcenowy Zheng { SP_OTP_KEY_PROTECT3_REG, SP_OTP_PSW3 }, 3255d97408eSIcenowy Zheng }; 3265d97408eSIcenowy Zheng 3275d97408eSIcenowy Zheng static int anx78xx_tx_initialization(struct anx78xx *anx78xx) 3285d97408eSIcenowy Zheng { 3295d97408eSIcenowy Zheng int err; 3305d97408eSIcenowy Zheng 3315d97408eSIcenowy Zheng /* Set terminal resistor to 50 ohm */ 3325d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_DP_AUX_CH_CTRL2_REG, 3335d97408eSIcenowy Zheng 0x30); 3345d97408eSIcenowy Zheng if (err) 3355d97408eSIcenowy Zheng return err; 3365d97408eSIcenowy Zheng 3375d97408eSIcenowy Zheng /* Enable aux double diff output */ 3385d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 3395d97408eSIcenowy Zheng SP_DP_AUX_CH_CTRL2_REG, 0x08); 3405d97408eSIcenowy Zheng if (err) 3415d97408eSIcenowy Zheng return err; 3425d97408eSIcenowy Zheng 3435d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P0], 3445d97408eSIcenowy Zheng SP_DP_HDCP_CTRL_REG, SP_AUTO_EN | 3455d97408eSIcenowy Zheng SP_AUTO_START); 3465d97408eSIcenowy Zheng if (err) 3475d97408eSIcenowy Zheng return err; 3485d97408eSIcenowy Zheng 3495d97408eSIcenowy Zheng err = regmap_multi_reg_write(anx78xx->map[I2C_IDX_TX_P0], 3505d97408eSIcenowy Zheng otp_key_protect, 3515d97408eSIcenowy Zheng ARRAY_SIZE(otp_key_protect)); 3525d97408eSIcenowy Zheng if (err) 3535d97408eSIcenowy Zheng return err; 3545d97408eSIcenowy Zheng 3555d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 3565d97408eSIcenowy Zheng SP_HDCP_KEY_COMMAND_REG, SP_DISABLE_SYNC_HDCP); 3575d97408eSIcenowy Zheng if (err) 3585d97408eSIcenowy Zheng return err; 3595d97408eSIcenowy Zheng 3605d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL8_REG, 3615d97408eSIcenowy Zheng SP_VID_VRES_TH); 3625d97408eSIcenowy Zheng if (err) 3635d97408eSIcenowy Zheng return err; 3645d97408eSIcenowy Zheng 3655d97408eSIcenowy Zheng /* 3665d97408eSIcenowy Zheng * DP HDCP auto authentication wait timer (when downstream starts to 3675d97408eSIcenowy Zheng * auth, DP side will wait for this period then do auth automatically) 3685d97408eSIcenowy Zheng */ 3695d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_HDCP_AUTO_TIMER_REG, 3705d97408eSIcenowy Zheng 0x00); 3715d97408eSIcenowy Zheng if (err) 3725d97408eSIcenowy Zheng return err; 3735d97408eSIcenowy Zheng 3745d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 3755d97408eSIcenowy Zheng SP_DP_HDCP_CTRL_REG, SP_LINK_POLLING); 3765d97408eSIcenowy Zheng if (err) 3775d97408eSIcenowy Zheng return err; 3785d97408eSIcenowy Zheng 3795d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 3805d97408eSIcenowy Zheng SP_DP_LINK_DEBUG_CTRL_REG, SP_M_VID_DEBUG); 3815d97408eSIcenowy Zheng if (err) 3825d97408eSIcenowy Zheng return err; 3835d97408eSIcenowy Zheng 3845d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], 3855d97408eSIcenowy Zheng SP_ANALOG_DEBUG2_REG, SP_POWERON_TIME_1P5MS); 3865d97408eSIcenowy Zheng if (err) 3875d97408eSIcenowy Zheng return err; 3885d97408eSIcenowy Zheng 3895d97408eSIcenowy Zheng err = anx78xx_xtal_clk_sel(anx78xx); 3905d97408eSIcenowy Zheng if (err) 3915d97408eSIcenowy Zheng return err; 3925d97408eSIcenowy Zheng 3935d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_AUX_DEFER_CTRL_REG, 3945d97408eSIcenowy Zheng SP_DEFER_CTRL_EN | 0x0c); 3955d97408eSIcenowy Zheng if (err) 3965d97408eSIcenowy Zheng return err; 3975d97408eSIcenowy Zheng 3985d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 3995d97408eSIcenowy Zheng SP_DP_POLLING_CTRL_REG, 4005d97408eSIcenowy Zheng SP_AUTO_POLLING_DISABLE); 4015d97408eSIcenowy Zheng if (err) 4025d97408eSIcenowy Zheng return err; 4035d97408eSIcenowy Zheng 4045d97408eSIcenowy Zheng /* 4055d97408eSIcenowy Zheng * Short the link integrity check timer to speed up bstatus 4065d97408eSIcenowy Zheng * polling for HDCP CTS item 1A-07 4075d97408eSIcenowy Zheng */ 4085d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 4095d97408eSIcenowy Zheng SP_HDCP_LINK_CHECK_TIMER_REG, 0x1d); 4105d97408eSIcenowy Zheng if (err) 4115d97408eSIcenowy Zheng return err; 4125d97408eSIcenowy Zheng 4135d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 4145d97408eSIcenowy Zheng SP_DP_MISC_CTRL_REG, SP_EQ_TRAINING_LOOP); 4155d97408eSIcenowy Zheng if (err) 4165d97408eSIcenowy Zheng return err; 4175d97408eSIcenowy Zheng 4185d97408eSIcenowy Zheng /* Power down the main link by default */ 4195d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 4205d97408eSIcenowy Zheng SP_DP_ANALOG_POWER_DOWN_REG, SP_CH0_PD); 4215d97408eSIcenowy Zheng if (err) 4225d97408eSIcenowy Zheng return err; 4235d97408eSIcenowy Zheng 4245d97408eSIcenowy Zheng err = anx78xx_link_phy_initialization(anx78xx); 4255d97408eSIcenowy Zheng if (err) 4265d97408eSIcenowy Zheng return err; 4275d97408eSIcenowy Zheng 4285d97408eSIcenowy Zheng /* Gen m_clk with downspreading */ 4295d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 4305d97408eSIcenowy Zheng SP_DP_M_CALCULATION_CTRL_REG, SP_M_GEN_CLK_SEL); 4315d97408eSIcenowy Zheng if (err) 4325d97408eSIcenowy Zheng return err; 4335d97408eSIcenowy Zheng 4345d97408eSIcenowy Zheng return 0; 4355d97408eSIcenowy Zheng } 4365d97408eSIcenowy Zheng 4375d97408eSIcenowy Zheng static int anx78xx_enable_interrupts(struct anx78xx *anx78xx) 4385d97408eSIcenowy Zheng { 4395d97408eSIcenowy Zheng int err; 4405d97408eSIcenowy Zheng 4415d97408eSIcenowy Zheng /* 4425d97408eSIcenowy Zheng * BIT0: INT pin assertion polarity: 1 = assert high 4435d97408eSIcenowy Zheng * BIT1: INT pin output type: 0 = push/pull 4445d97408eSIcenowy Zheng */ 4455d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], SP_INT_CTRL_REG, 0x01); 4465d97408eSIcenowy Zheng if (err) 4475d97408eSIcenowy Zheng return err; 4485d97408eSIcenowy Zheng 4495d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], 4505d97408eSIcenowy Zheng SP_COMMON_INT_MASK4_REG, SP_HPD_LOST | SP_HPD_PLUG); 4515d97408eSIcenowy Zheng if (err) 4525d97408eSIcenowy Zheng return err; 4535d97408eSIcenowy Zheng 4545d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], SP_DP_INT_MASK1_REG, 4555d97408eSIcenowy Zheng SP_TRAINING_FINISH); 4565d97408eSIcenowy Zheng if (err) 4575d97408eSIcenowy Zheng return err; 4585d97408eSIcenowy Zheng 4595d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_RX_P0], SP_INT_MASK1_REG, 4605d97408eSIcenowy Zheng SP_CKDT_CHG | SP_SCDT_CHG); 4615d97408eSIcenowy Zheng if (err) 4625d97408eSIcenowy Zheng return err; 4635d97408eSIcenowy Zheng 4645d97408eSIcenowy Zheng return 0; 4655d97408eSIcenowy Zheng } 4665d97408eSIcenowy Zheng 4675d97408eSIcenowy Zheng static void anx78xx_poweron(struct anx78xx *anx78xx) 4685d97408eSIcenowy Zheng { 4695d97408eSIcenowy Zheng struct anx78xx_platform_data *pdata = &anx78xx->pdata; 4705d97408eSIcenowy Zheng int err; 4715d97408eSIcenowy Zheng 4725d97408eSIcenowy Zheng if (WARN_ON(anx78xx->powered)) 4735d97408eSIcenowy Zheng return; 4745d97408eSIcenowy Zheng 4755d97408eSIcenowy Zheng if (pdata->dvdd10) { 4765d97408eSIcenowy Zheng err = regulator_enable(pdata->dvdd10); 4775d97408eSIcenowy Zheng if (err) { 4785d97408eSIcenowy Zheng DRM_ERROR("Failed to enable DVDD10 regulator: %d\n", 4795d97408eSIcenowy Zheng err); 4805d97408eSIcenowy Zheng return; 4815d97408eSIcenowy Zheng } 4825d97408eSIcenowy Zheng 4835d97408eSIcenowy Zheng usleep_range(1000, 2000); 4845d97408eSIcenowy Zheng } 4855d97408eSIcenowy Zheng 4865d97408eSIcenowy Zheng gpiod_set_value_cansleep(pdata->gpiod_reset, 1); 4875d97408eSIcenowy Zheng usleep_range(1000, 2000); 4885d97408eSIcenowy Zheng 4895d97408eSIcenowy Zheng gpiod_set_value_cansleep(pdata->gpiod_pd, 0); 4905d97408eSIcenowy Zheng usleep_range(1000, 2000); 4915d97408eSIcenowy Zheng 4925d97408eSIcenowy Zheng gpiod_set_value_cansleep(pdata->gpiod_reset, 0); 4935d97408eSIcenowy Zheng 4945d97408eSIcenowy Zheng /* Power on registers module */ 4955d97408eSIcenowy Zheng anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], SP_POWERDOWN_CTRL_REG, 4965d97408eSIcenowy Zheng SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD); 4975d97408eSIcenowy Zheng anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], SP_POWERDOWN_CTRL_REG, 4985d97408eSIcenowy Zheng SP_REGISTER_PD | SP_TOTAL_PD); 4995d97408eSIcenowy Zheng 5005d97408eSIcenowy Zheng anx78xx->powered = true; 5015d97408eSIcenowy Zheng } 5025d97408eSIcenowy Zheng 5035d97408eSIcenowy Zheng static void anx78xx_poweroff(struct anx78xx *anx78xx) 5045d97408eSIcenowy Zheng { 5055d97408eSIcenowy Zheng struct anx78xx_platform_data *pdata = &anx78xx->pdata; 5065d97408eSIcenowy Zheng int err; 5075d97408eSIcenowy Zheng 5085d97408eSIcenowy Zheng if (WARN_ON(!anx78xx->powered)) 5095d97408eSIcenowy Zheng return; 5105d97408eSIcenowy Zheng 5115d97408eSIcenowy Zheng gpiod_set_value_cansleep(pdata->gpiod_reset, 1); 5125d97408eSIcenowy Zheng usleep_range(1000, 2000); 5135d97408eSIcenowy Zheng 5145d97408eSIcenowy Zheng gpiod_set_value_cansleep(pdata->gpiod_pd, 1); 5155d97408eSIcenowy Zheng usleep_range(1000, 2000); 5165d97408eSIcenowy Zheng 5175d97408eSIcenowy Zheng if (pdata->dvdd10) { 5185d97408eSIcenowy Zheng err = regulator_disable(pdata->dvdd10); 5195d97408eSIcenowy Zheng if (err) { 5205d97408eSIcenowy Zheng DRM_ERROR("Failed to disable DVDD10 regulator: %d\n", 5215d97408eSIcenowy Zheng err); 5225d97408eSIcenowy Zheng return; 5235d97408eSIcenowy Zheng } 5245d97408eSIcenowy Zheng 5255d97408eSIcenowy Zheng usleep_range(1000, 2000); 5265d97408eSIcenowy Zheng } 5275d97408eSIcenowy Zheng 5285d97408eSIcenowy Zheng anx78xx->powered = false; 5295d97408eSIcenowy Zheng } 5305d97408eSIcenowy Zheng 5315d97408eSIcenowy Zheng static int anx78xx_start(struct anx78xx *anx78xx) 5325d97408eSIcenowy Zheng { 5335d97408eSIcenowy Zheng int err; 5345d97408eSIcenowy Zheng 5355d97408eSIcenowy Zheng /* Power on all modules */ 5365d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], 5375d97408eSIcenowy Zheng SP_POWERDOWN_CTRL_REG, 5385d97408eSIcenowy Zheng SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | 5395d97408eSIcenowy Zheng SP_LINK_PD); 5405d97408eSIcenowy Zheng 5415d97408eSIcenowy Zheng err = anx78xx_enable_interrupts(anx78xx); 5425d97408eSIcenowy Zheng if (err) { 5435d97408eSIcenowy Zheng DRM_ERROR("Failed to enable interrupts: %d\n", err); 5445d97408eSIcenowy Zheng goto err_poweroff; 5455d97408eSIcenowy Zheng } 5465d97408eSIcenowy Zheng 5475d97408eSIcenowy Zheng err = anx78xx_rx_initialization(anx78xx); 5485d97408eSIcenowy Zheng if (err) { 5495d97408eSIcenowy Zheng DRM_ERROR("Failed receiver initialization: %d\n", err); 5505d97408eSIcenowy Zheng goto err_poweroff; 5515d97408eSIcenowy Zheng } 5525d97408eSIcenowy Zheng 5535d97408eSIcenowy Zheng err = anx78xx_tx_initialization(anx78xx); 5545d97408eSIcenowy Zheng if (err) { 5555d97408eSIcenowy Zheng DRM_ERROR("Failed transmitter initialization: %d\n", err); 5565d97408eSIcenowy Zheng goto err_poweroff; 5575d97408eSIcenowy Zheng } 5585d97408eSIcenowy Zheng 5595d97408eSIcenowy Zheng /* 5605d97408eSIcenowy Zheng * This delay seems to help keep the hardware in a good state. Without 5615d97408eSIcenowy Zheng * it, there are times where it fails silently. 5625d97408eSIcenowy Zheng */ 5635d97408eSIcenowy Zheng usleep_range(10000, 15000); 5645d97408eSIcenowy Zheng 5655d97408eSIcenowy Zheng return 0; 5665d97408eSIcenowy Zheng 5675d97408eSIcenowy Zheng err_poweroff: 5685d97408eSIcenowy Zheng DRM_ERROR("Failed SlimPort transmitter initialization: %d\n", err); 5695d97408eSIcenowy Zheng anx78xx_poweroff(anx78xx); 5705d97408eSIcenowy Zheng 5715d97408eSIcenowy Zheng return err; 5725d97408eSIcenowy Zheng } 5735d97408eSIcenowy Zheng 5745d97408eSIcenowy Zheng static int anx78xx_init_pdata(struct anx78xx *anx78xx) 5755d97408eSIcenowy Zheng { 5765d97408eSIcenowy Zheng struct anx78xx_platform_data *pdata = &anx78xx->pdata; 5775d97408eSIcenowy Zheng struct device *dev = &anx78xx->client->dev; 5785d97408eSIcenowy Zheng 5795d97408eSIcenowy Zheng /* 1.0V digital core power regulator */ 5805d97408eSIcenowy Zheng pdata->dvdd10 = devm_regulator_get(dev, "dvdd10"); 5815d97408eSIcenowy Zheng if (IS_ERR(pdata->dvdd10)) { 5825d97408eSIcenowy Zheng if (PTR_ERR(pdata->dvdd10) != -EPROBE_DEFER) 5835d97408eSIcenowy Zheng DRM_ERROR("DVDD10 regulator not found\n"); 5845d97408eSIcenowy Zheng 5855d97408eSIcenowy Zheng return PTR_ERR(pdata->dvdd10); 5865d97408eSIcenowy Zheng } 5875d97408eSIcenowy Zheng 5885d97408eSIcenowy Zheng /* GPIO for HPD */ 5895d97408eSIcenowy Zheng pdata->gpiod_hpd = devm_gpiod_get(dev, "hpd", GPIOD_IN); 5905d97408eSIcenowy Zheng if (IS_ERR(pdata->gpiod_hpd)) 5915d97408eSIcenowy Zheng return PTR_ERR(pdata->gpiod_hpd); 5925d97408eSIcenowy Zheng 5935d97408eSIcenowy Zheng /* GPIO for chip power down */ 5945d97408eSIcenowy Zheng pdata->gpiod_pd = devm_gpiod_get(dev, "pd", GPIOD_OUT_HIGH); 5955d97408eSIcenowy Zheng if (IS_ERR(pdata->gpiod_pd)) 5965d97408eSIcenowy Zheng return PTR_ERR(pdata->gpiod_pd); 5975d97408eSIcenowy Zheng 5985d97408eSIcenowy Zheng /* GPIO for chip reset */ 5995d97408eSIcenowy Zheng pdata->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 6005d97408eSIcenowy Zheng 6015d97408eSIcenowy Zheng return PTR_ERR_OR_ZERO(pdata->gpiod_reset); 6025d97408eSIcenowy Zheng } 6035d97408eSIcenowy Zheng 6045d97408eSIcenowy Zheng static int anx78xx_dp_link_training(struct anx78xx *anx78xx) 6055d97408eSIcenowy Zheng { 6065d97408eSIcenowy Zheng u8 dp_bw, dpcd[2]; 6075d97408eSIcenowy Zheng int err; 6085d97408eSIcenowy Zheng 6095d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_RX_P0], SP_HDMI_MUTE_CTRL_REG, 6105d97408eSIcenowy Zheng 0x0); 6115d97408eSIcenowy Zheng if (err) 6125d97408eSIcenowy Zheng return err; 6135d97408eSIcenowy Zheng 6145d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], 6155d97408eSIcenowy Zheng SP_POWERDOWN_CTRL_REG, 6165d97408eSIcenowy Zheng SP_TOTAL_PD); 6175d97408eSIcenowy Zheng if (err) 6185d97408eSIcenowy Zheng return err; 6195d97408eSIcenowy Zheng 6205d97408eSIcenowy Zheng err = drm_dp_dpcd_readb(&anx78xx->aux, DP_MAX_LINK_RATE, &dp_bw); 6215d97408eSIcenowy Zheng if (err < 0) 6225d97408eSIcenowy Zheng return err; 6235d97408eSIcenowy Zheng 6245d97408eSIcenowy Zheng switch (dp_bw) { 6255d97408eSIcenowy Zheng case DP_LINK_BW_1_62: 6265d97408eSIcenowy Zheng case DP_LINK_BW_2_7: 6275d97408eSIcenowy Zheng case DP_LINK_BW_5_4: 6285d97408eSIcenowy Zheng break; 6295d97408eSIcenowy Zheng 6305d97408eSIcenowy Zheng default: 6315d97408eSIcenowy Zheng DRM_DEBUG_KMS("DP bandwidth (%#02x) not supported\n", dp_bw); 6325d97408eSIcenowy Zheng return -EINVAL; 6335d97408eSIcenowy Zheng } 6345d97408eSIcenowy Zheng 6355d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL1_REG, 6365d97408eSIcenowy Zheng SP_VIDEO_MUTE); 6375d97408eSIcenowy Zheng if (err) 6385d97408eSIcenowy Zheng return err; 6395d97408eSIcenowy Zheng 6405d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], 6415d97408eSIcenowy Zheng SP_VID_CTRL1_REG, SP_VIDEO_EN); 6425d97408eSIcenowy Zheng if (err) 6435d97408eSIcenowy Zheng return err; 6445d97408eSIcenowy Zheng 6455d97408eSIcenowy Zheng /* Get DPCD info */ 6465d97408eSIcenowy Zheng err = drm_dp_dpcd_read(&anx78xx->aux, DP_DPCD_REV, 6475d97408eSIcenowy Zheng &anx78xx->dpcd, DP_RECEIVER_CAP_SIZE); 6485d97408eSIcenowy Zheng if (err < 0) { 6495d97408eSIcenowy Zheng DRM_ERROR("Failed to read DPCD: %d\n", err); 6505d97408eSIcenowy Zheng return err; 6515d97408eSIcenowy Zheng } 6525d97408eSIcenowy Zheng 6535d97408eSIcenowy Zheng /* Clear channel x SERDES power down */ 6545d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P0], 6555d97408eSIcenowy Zheng SP_DP_ANALOG_POWER_DOWN_REG, SP_CH0_PD); 6565d97408eSIcenowy Zheng if (err) 6575d97408eSIcenowy Zheng return err; 6585d97408eSIcenowy Zheng 6595d97408eSIcenowy Zheng /* 6605d97408eSIcenowy Zheng * Power up the sink (DP_SET_POWER register is only available on DPCD 6615d97408eSIcenowy Zheng * v1.1 and later). 6625d97408eSIcenowy Zheng */ 6635d97408eSIcenowy Zheng if (anx78xx->dpcd[DP_DPCD_REV] >= 0x11) { 6645d97408eSIcenowy Zheng err = drm_dp_dpcd_readb(&anx78xx->aux, DP_SET_POWER, &dpcd[0]); 6655d97408eSIcenowy Zheng if (err < 0) { 6665d97408eSIcenowy Zheng DRM_ERROR("Failed to read DP_SET_POWER register: %d\n", 6675d97408eSIcenowy Zheng err); 6685d97408eSIcenowy Zheng return err; 6695d97408eSIcenowy Zheng } 6705d97408eSIcenowy Zheng 6715d97408eSIcenowy Zheng dpcd[0] &= ~DP_SET_POWER_MASK; 6725d97408eSIcenowy Zheng dpcd[0] |= DP_SET_POWER_D0; 6735d97408eSIcenowy Zheng 6745d97408eSIcenowy Zheng err = drm_dp_dpcd_writeb(&anx78xx->aux, DP_SET_POWER, dpcd[0]); 6755d97408eSIcenowy Zheng if (err < 0) { 6765d97408eSIcenowy Zheng DRM_ERROR("Failed to power up DisplayPort link: %d\n", 6775d97408eSIcenowy Zheng err); 6785d97408eSIcenowy Zheng return err; 6795d97408eSIcenowy Zheng } 6805d97408eSIcenowy Zheng 6815d97408eSIcenowy Zheng /* 6825d97408eSIcenowy Zheng * According to the DP 1.1 specification, a "Sink Device must 6835d97408eSIcenowy Zheng * exit the power saving state within 1 ms" (Section 2.5.3.1, 6845d97408eSIcenowy Zheng * Table 5-52, "Sink Control Field" (register 0x600). 6855d97408eSIcenowy Zheng */ 6865d97408eSIcenowy Zheng usleep_range(1000, 2000); 6875d97408eSIcenowy Zheng } 6885d97408eSIcenowy Zheng 6895d97408eSIcenowy Zheng /* Possibly enable downspread on the sink */ 6905d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 6915d97408eSIcenowy Zheng SP_DP_DOWNSPREAD_CTRL1_REG, 0); 6925d97408eSIcenowy Zheng if (err) 6935d97408eSIcenowy Zheng return err; 6945d97408eSIcenowy Zheng 6955d97408eSIcenowy Zheng if (anx78xx->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5) { 6965d97408eSIcenowy Zheng DRM_DEBUG("Enable downspread on the sink\n"); 6975d97408eSIcenowy Zheng /* 4000PPM */ 6985d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 6995d97408eSIcenowy Zheng SP_DP_DOWNSPREAD_CTRL1_REG, 8); 7005d97408eSIcenowy Zheng if (err) 7015d97408eSIcenowy Zheng return err; 7025d97408eSIcenowy Zheng 7035d97408eSIcenowy Zheng err = drm_dp_dpcd_writeb(&anx78xx->aux, DP_DOWNSPREAD_CTRL, 7045d97408eSIcenowy Zheng DP_SPREAD_AMP_0_5); 7055d97408eSIcenowy Zheng if (err < 0) 7065d97408eSIcenowy Zheng return err; 7075d97408eSIcenowy Zheng } else { 7085d97408eSIcenowy Zheng err = drm_dp_dpcd_writeb(&anx78xx->aux, DP_DOWNSPREAD_CTRL, 0); 7095d97408eSIcenowy Zheng if (err < 0) 7105d97408eSIcenowy Zheng return err; 7115d97408eSIcenowy Zheng } 7125d97408eSIcenowy Zheng 7135d97408eSIcenowy Zheng /* Set the lane count and the link rate on the sink */ 7145d97408eSIcenowy Zheng if (drm_dp_enhanced_frame_cap(anx78xx->dpcd)) 7155d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 7165d97408eSIcenowy Zheng SP_DP_SYSTEM_CTRL_BASE + 4, 7175d97408eSIcenowy Zheng SP_ENHANCED_MODE); 7185d97408eSIcenowy Zheng else 7195d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P0], 7205d97408eSIcenowy Zheng SP_DP_SYSTEM_CTRL_BASE + 4, 7215d97408eSIcenowy Zheng SP_ENHANCED_MODE); 7225d97408eSIcenowy Zheng if (err) 7235d97408eSIcenowy Zheng return err; 7245d97408eSIcenowy Zheng 7255d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], 7263e138a63STorsten Duwe SP_DP_MAIN_LINK_BW_SET_REG, 7273e138a63STorsten Duwe anx78xx->dpcd[DP_MAX_LINK_RATE]); 7285d97408eSIcenowy Zheng if (err) 7295d97408eSIcenowy Zheng return err; 7305d97408eSIcenowy Zheng 7315d97408eSIcenowy Zheng dpcd[1] = drm_dp_max_lane_count(anx78xx->dpcd); 7325d97408eSIcenowy Zheng 7335d97408eSIcenowy Zheng if (drm_dp_enhanced_frame_cap(anx78xx->dpcd)) 7345d97408eSIcenowy Zheng dpcd[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 7355d97408eSIcenowy Zheng 7365d97408eSIcenowy Zheng err = drm_dp_dpcd_write(&anx78xx->aux, DP_LINK_BW_SET, dpcd, 7375d97408eSIcenowy Zheng sizeof(dpcd)); 7385d97408eSIcenowy Zheng if (err < 0) { 7395d97408eSIcenowy Zheng DRM_ERROR("Failed to configure link: %d\n", err); 7405d97408eSIcenowy Zheng return err; 7415d97408eSIcenowy Zheng } 7425d97408eSIcenowy Zheng 7435d97408eSIcenowy Zheng /* Start training on the source */ 7445d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P0], SP_DP_LT_CTRL_REG, 7455d97408eSIcenowy Zheng SP_LT_EN); 7465d97408eSIcenowy Zheng if (err) 7475d97408eSIcenowy Zheng return err; 7485d97408eSIcenowy Zheng 7495d97408eSIcenowy Zheng return 0; 7505d97408eSIcenowy Zheng } 7515d97408eSIcenowy Zheng 7525d97408eSIcenowy Zheng static int anx78xx_config_dp_output(struct anx78xx *anx78xx) 7535d97408eSIcenowy Zheng { 7545d97408eSIcenowy Zheng int err; 7555d97408eSIcenowy Zheng 7565d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL1_REG, 7575d97408eSIcenowy Zheng SP_VIDEO_MUTE); 7585d97408eSIcenowy Zheng if (err) 7595d97408eSIcenowy Zheng return err; 7605d97408eSIcenowy Zheng 7615d97408eSIcenowy Zheng /* Enable DP output */ 7625d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], SP_VID_CTRL1_REG, 7635d97408eSIcenowy Zheng SP_VIDEO_EN); 7645d97408eSIcenowy Zheng if (err) 7655d97408eSIcenowy Zheng return err; 7665d97408eSIcenowy Zheng 7675d97408eSIcenowy Zheng return 0; 7685d97408eSIcenowy Zheng } 7695d97408eSIcenowy Zheng 7705d97408eSIcenowy Zheng static int anx78xx_send_video_infoframe(struct anx78xx *anx78xx, 7715d97408eSIcenowy Zheng struct hdmi_avi_infoframe *frame) 7725d97408eSIcenowy Zheng { 7735d97408eSIcenowy Zheng u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; 7745d97408eSIcenowy Zheng int err; 7755d97408eSIcenowy Zheng 7765d97408eSIcenowy Zheng err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer)); 7775d97408eSIcenowy Zheng if (err < 0) { 7785d97408eSIcenowy Zheng DRM_ERROR("Failed to pack AVI infoframe: %d\n", err); 7795d97408eSIcenowy Zheng return err; 7805d97408eSIcenowy Zheng } 7815d97408eSIcenowy Zheng 7825d97408eSIcenowy Zheng err = anx78xx_clear_bits(anx78xx->map[I2C_IDX_TX_P0], 7835d97408eSIcenowy Zheng SP_PACKET_SEND_CTRL_REG, SP_AVI_IF_EN); 7845d97408eSIcenowy Zheng if (err) 7855d97408eSIcenowy Zheng return err; 7865d97408eSIcenowy Zheng 7875d97408eSIcenowy Zheng err = regmap_bulk_write(anx78xx->map[I2C_IDX_TX_P2], 7885d97408eSIcenowy Zheng SP_INFOFRAME_AVI_DB1_REG, buffer, 7895d97408eSIcenowy Zheng frame->length); 7905d97408eSIcenowy Zheng if (err) 7915d97408eSIcenowy Zheng return err; 7925d97408eSIcenowy Zheng 7935d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 7945d97408eSIcenowy Zheng SP_PACKET_SEND_CTRL_REG, SP_AVI_IF_UD); 7955d97408eSIcenowy Zheng if (err) 7965d97408eSIcenowy Zheng return err; 7975d97408eSIcenowy Zheng 7985d97408eSIcenowy Zheng err = anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P0], 7995d97408eSIcenowy Zheng SP_PACKET_SEND_CTRL_REG, SP_AVI_IF_EN); 8005d97408eSIcenowy Zheng if (err) 8015d97408eSIcenowy Zheng return err; 8025d97408eSIcenowy Zheng 8035d97408eSIcenowy Zheng return 0; 8045d97408eSIcenowy Zheng } 8055d97408eSIcenowy Zheng 8065d97408eSIcenowy Zheng static int anx78xx_get_downstream_info(struct anx78xx *anx78xx) 8075d97408eSIcenowy Zheng { 8085d97408eSIcenowy Zheng u8 value; 8095d97408eSIcenowy Zheng int err; 8105d97408eSIcenowy Zheng 8115d97408eSIcenowy Zheng err = drm_dp_dpcd_readb(&anx78xx->aux, DP_SINK_COUNT, &value); 8125d97408eSIcenowy Zheng if (err < 0) { 8135d97408eSIcenowy Zheng DRM_ERROR("Get sink count failed %d\n", err); 8145d97408eSIcenowy Zheng return err; 8155d97408eSIcenowy Zheng } 8165d97408eSIcenowy Zheng 8175d97408eSIcenowy Zheng if (!DP_GET_SINK_COUNT(value)) { 8185d97408eSIcenowy Zheng DRM_ERROR("Downstream disconnected\n"); 8195d97408eSIcenowy Zheng return -EIO; 8205d97408eSIcenowy Zheng } 8215d97408eSIcenowy Zheng 8225d97408eSIcenowy Zheng return 0; 8235d97408eSIcenowy Zheng } 8245d97408eSIcenowy Zheng 8255d97408eSIcenowy Zheng static int anx78xx_get_modes(struct drm_connector *connector) 8265d97408eSIcenowy Zheng { 8275d97408eSIcenowy Zheng struct anx78xx *anx78xx = connector_to_anx78xx(connector); 8285d97408eSIcenowy Zheng int err, num_modes = 0; 8295d97408eSIcenowy Zheng 8305d97408eSIcenowy Zheng if (WARN_ON(!anx78xx->powered)) 8315d97408eSIcenowy Zheng return 0; 8325d97408eSIcenowy Zheng 8335d97408eSIcenowy Zheng if (anx78xx->edid) 8345d97408eSIcenowy Zheng return drm_add_edid_modes(connector, anx78xx->edid); 8355d97408eSIcenowy Zheng 8365d97408eSIcenowy Zheng mutex_lock(&anx78xx->lock); 8375d97408eSIcenowy Zheng 8385d97408eSIcenowy Zheng err = anx78xx_get_downstream_info(anx78xx); 8395d97408eSIcenowy Zheng if (err) { 8405d97408eSIcenowy Zheng DRM_ERROR("Failed to get downstream info: %d\n", err); 8415d97408eSIcenowy Zheng goto unlock; 8425d97408eSIcenowy Zheng } 8435d97408eSIcenowy Zheng 8445d97408eSIcenowy Zheng anx78xx->edid = drm_get_edid(connector, &anx78xx->aux.ddc); 8455d97408eSIcenowy Zheng if (!anx78xx->edid) { 8465d97408eSIcenowy Zheng DRM_ERROR("Failed to read EDID\n"); 8475d97408eSIcenowy Zheng goto unlock; 8485d97408eSIcenowy Zheng } 8495d97408eSIcenowy Zheng 8505d97408eSIcenowy Zheng err = drm_connector_update_edid_property(connector, 8515d97408eSIcenowy Zheng anx78xx->edid); 8525d97408eSIcenowy Zheng if (err) { 8535d97408eSIcenowy Zheng DRM_ERROR("Failed to update EDID property: %d\n", err); 8545d97408eSIcenowy Zheng goto unlock; 8555d97408eSIcenowy Zheng } 8565d97408eSIcenowy Zheng 8575d97408eSIcenowy Zheng num_modes = drm_add_edid_modes(connector, anx78xx->edid); 8585d97408eSIcenowy Zheng 8595d97408eSIcenowy Zheng unlock: 8605d97408eSIcenowy Zheng mutex_unlock(&anx78xx->lock); 8615d97408eSIcenowy Zheng 8625d97408eSIcenowy Zheng return num_modes; 8635d97408eSIcenowy Zheng } 8645d97408eSIcenowy Zheng 8655d97408eSIcenowy Zheng static const struct drm_connector_helper_funcs anx78xx_connector_helper_funcs = { 8665d97408eSIcenowy Zheng .get_modes = anx78xx_get_modes, 8675d97408eSIcenowy Zheng }; 8685d97408eSIcenowy Zheng 8695d97408eSIcenowy Zheng static enum drm_connector_status anx78xx_detect(struct drm_connector *connector, 8705d97408eSIcenowy Zheng bool force) 8715d97408eSIcenowy Zheng { 8725d97408eSIcenowy Zheng struct anx78xx *anx78xx = connector_to_anx78xx(connector); 8735d97408eSIcenowy Zheng 8745d97408eSIcenowy Zheng if (!gpiod_get_value(anx78xx->pdata.gpiod_hpd)) 8755d97408eSIcenowy Zheng return connector_status_disconnected; 8765d97408eSIcenowy Zheng 8775d97408eSIcenowy Zheng return connector_status_connected; 8785d97408eSIcenowy Zheng } 8795d97408eSIcenowy Zheng 8805d97408eSIcenowy Zheng static const struct drm_connector_funcs anx78xx_connector_funcs = { 8815d97408eSIcenowy Zheng .fill_modes = drm_helper_probe_single_connector_modes, 8825d97408eSIcenowy Zheng .detect = anx78xx_detect, 8835d97408eSIcenowy Zheng .destroy = drm_connector_cleanup, 8845d97408eSIcenowy Zheng .reset = drm_atomic_helper_connector_reset, 8855d97408eSIcenowy Zheng .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 8865d97408eSIcenowy Zheng .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 8875d97408eSIcenowy Zheng }; 8885d97408eSIcenowy Zheng 889a25b988fSLaurent Pinchart static int anx78xx_bridge_attach(struct drm_bridge *bridge, 890a25b988fSLaurent Pinchart enum drm_bridge_attach_flags flags) 8915d97408eSIcenowy Zheng { 8925d97408eSIcenowy Zheng struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); 8935d97408eSIcenowy Zheng int err; 8945d97408eSIcenowy Zheng 895a25b988fSLaurent Pinchart if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { 896a25b988fSLaurent Pinchart DRM_ERROR("Fix bridge driver to make connector optional!"); 897a25b988fSLaurent Pinchart return -EINVAL; 898a25b988fSLaurent Pinchart } 899a25b988fSLaurent Pinchart 9005d97408eSIcenowy Zheng if (!bridge->encoder) { 9015d97408eSIcenowy Zheng DRM_ERROR("Parent encoder object not found"); 9025d97408eSIcenowy Zheng return -ENODEV; 9035d97408eSIcenowy Zheng } 9045d97408eSIcenowy Zheng 9055d97408eSIcenowy Zheng /* Register aux channel */ 9065d97408eSIcenowy Zheng anx78xx->aux.name = "DP-AUX"; 9075d97408eSIcenowy Zheng anx78xx->aux.dev = &anx78xx->client->dev; 9086cba3fe4SLyude Paul anx78xx->aux.drm_dev = bridge->dev; 9095d97408eSIcenowy Zheng anx78xx->aux.transfer = anx78xx_aux_transfer; 9105d97408eSIcenowy Zheng 9115d97408eSIcenowy Zheng err = drm_dp_aux_register(&anx78xx->aux); 9125d97408eSIcenowy Zheng if (err < 0) { 9135d97408eSIcenowy Zheng DRM_ERROR("Failed to register aux channel: %d\n", err); 9145d97408eSIcenowy Zheng return err; 9155d97408eSIcenowy Zheng } 9165d97408eSIcenowy Zheng 9175d97408eSIcenowy Zheng err = drm_connector_init(bridge->dev, &anx78xx->connector, 9185d97408eSIcenowy Zheng &anx78xx_connector_funcs, 9195d97408eSIcenowy Zheng DRM_MODE_CONNECTOR_DisplayPort); 9205d97408eSIcenowy Zheng if (err) { 9215d97408eSIcenowy Zheng DRM_ERROR("Failed to initialize connector: %d\n", err); 922212ee8dbSLyude Paul goto aux_unregister; 9235d97408eSIcenowy Zheng } 9245d97408eSIcenowy Zheng 9255d97408eSIcenowy Zheng drm_connector_helper_add(&anx78xx->connector, 9265d97408eSIcenowy Zheng &anx78xx_connector_helper_funcs); 9275d97408eSIcenowy Zheng 9285d97408eSIcenowy Zheng anx78xx->connector.polled = DRM_CONNECTOR_POLL_HPD; 9295d97408eSIcenowy Zheng 9305d97408eSIcenowy Zheng err = drm_connector_attach_encoder(&anx78xx->connector, 9315d97408eSIcenowy Zheng bridge->encoder); 9325d97408eSIcenowy Zheng if (err) { 9335d97408eSIcenowy Zheng DRM_ERROR("Failed to link up connector to encoder: %d\n", err); 934212ee8dbSLyude Paul goto connector_cleanup; 9355d97408eSIcenowy Zheng } 9365d97408eSIcenowy Zheng 9379962849dSLyude Paul err = drm_connector_register(&anx78xx->connector); 9389962849dSLyude Paul if (err) { 9399962849dSLyude Paul DRM_ERROR("Failed to register connector: %d\n", err); 940212ee8dbSLyude Paul goto connector_cleanup; 9419962849dSLyude Paul } 9429962849dSLyude Paul 9435d97408eSIcenowy Zheng return 0; 944212ee8dbSLyude Paul connector_cleanup: 945212ee8dbSLyude Paul drm_connector_cleanup(&anx78xx->connector); 946212ee8dbSLyude Paul aux_unregister: 947212ee8dbSLyude Paul drm_dp_aux_unregister(&anx78xx->aux); 948212ee8dbSLyude Paul return err; 9495d97408eSIcenowy Zheng } 9505d97408eSIcenowy Zheng 951885373dbSLyude Paul static void anx78xx_bridge_detach(struct drm_bridge *bridge) 952885373dbSLyude Paul { 953885373dbSLyude Paul drm_dp_aux_unregister(&bridge_to_anx78xx(bridge)->aux); 954885373dbSLyude Paul } 955885373dbSLyude Paul 9565d97408eSIcenowy Zheng static enum drm_mode_status 9575d97408eSIcenowy Zheng anx78xx_bridge_mode_valid(struct drm_bridge *bridge, 95812c683e1SLaurent Pinchart const struct drm_display_info *info, 9595d97408eSIcenowy Zheng const struct drm_display_mode *mode) 9605d97408eSIcenowy Zheng { 9615d97408eSIcenowy Zheng if (mode->flags & DRM_MODE_FLAG_INTERLACE) 9625d97408eSIcenowy Zheng return MODE_NO_INTERLACE; 9635d97408eSIcenowy Zheng 9645d97408eSIcenowy Zheng /* Max 1200p at 5.4 Ghz, one lane */ 9655d97408eSIcenowy Zheng if (mode->clock > 154000) 9665d97408eSIcenowy Zheng return MODE_CLOCK_HIGH; 9675d97408eSIcenowy Zheng 9685d97408eSIcenowy Zheng return MODE_OK; 9695d97408eSIcenowy Zheng } 9705d97408eSIcenowy Zheng 9715d97408eSIcenowy Zheng static void anx78xx_bridge_disable(struct drm_bridge *bridge) 9725d97408eSIcenowy Zheng { 9735d97408eSIcenowy Zheng struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); 9745d97408eSIcenowy Zheng 9755d97408eSIcenowy Zheng /* Power off all modules except configuration registers access */ 9765d97408eSIcenowy Zheng anx78xx_set_bits(anx78xx->map[I2C_IDX_TX_P2], SP_POWERDOWN_CTRL_REG, 9775d97408eSIcenowy Zheng SP_HDCP_PD | SP_AUDIO_PD | SP_VIDEO_PD | SP_LINK_PD); 9785d97408eSIcenowy Zheng } 9795d97408eSIcenowy Zheng 9805d97408eSIcenowy Zheng static void anx78xx_bridge_mode_set(struct drm_bridge *bridge, 9815d97408eSIcenowy Zheng const struct drm_display_mode *mode, 9825d97408eSIcenowy Zheng const struct drm_display_mode *adjusted_mode) 9835d97408eSIcenowy Zheng { 9845d97408eSIcenowy Zheng struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); 9855d97408eSIcenowy Zheng struct hdmi_avi_infoframe frame; 9865d97408eSIcenowy Zheng int err; 9875d97408eSIcenowy Zheng 9885d97408eSIcenowy Zheng if (WARN_ON(!anx78xx->powered)) 9895d97408eSIcenowy Zheng return; 9905d97408eSIcenowy Zheng 9915d97408eSIcenowy Zheng mutex_lock(&anx78xx->lock); 9925d97408eSIcenowy Zheng 9935d97408eSIcenowy Zheng err = drm_hdmi_avi_infoframe_from_display_mode(&frame, 9945d97408eSIcenowy Zheng &anx78xx->connector, 9955d97408eSIcenowy Zheng adjusted_mode); 9965d97408eSIcenowy Zheng if (err) { 9975d97408eSIcenowy Zheng DRM_ERROR("Failed to setup AVI infoframe: %d\n", err); 9985d97408eSIcenowy Zheng goto unlock; 9995d97408eSIcenowy Zheng } 10005d97408eSIcenowy Zheng 10015d97408eSIcenowy Zheng err = anx78xx_send_video_infoframe(anx78xx, &frame); 10025d97408eSIcenowy Zheng if (err) 10035d97408eSIcenowy Zheng DRM_ERROR("Failed to send AVI infoframe: %d\n", err); 10045d97408eSIcenowy Zheng 10055d97408eSIcenowy Zheng unlock: 10065d97408eSIcenowy Zheng mutex_unlock(&anx78xx->lock); 10075d97408eSIcenowy Zheng } 10085d97408eSIcenowy Zheng 10095d97408eSIcenowy Zheng static void anx78xx_bridge_enable(struct drm_bridge *bridge) 10105d97408eSIcenowy Zheng { 10115d97408eSIcenowy Zheng struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); 10125d97408eSIcenowy Zheng int err; 10135d97408eSIcenowy Zheng 10145d97408eSIcenowy Zheng err = anx78xx_start(anx78xx); 10155d97408eSIcenowy Zheng if (err) { 10165d97408eSIcenowy Zheng DRM_ERROR("Failed to initialize: %d\n", err); 10175d97408eSIcenowy Zheng return; 10185d97408eSIcenowy Zheng } 10195d97408eSIcenowy Zheng 10205d97408eSIcenowy Zheng err = anx78xx_set_hpd(anx78xx); 10215d97408eSIcenowy Zheng if (err) 10225d97408eSIcenowy Zheng DRM_ERROR("Failed to set HPD: %d\n", err); 10235d97408eSIcenowy Zheng } 10245d97408eSIcenowy Zheng 10255d97408eSIcenowy Zheng static const struct drm_bridge_funcs anx78xx_bridge_funcs = { 10265d97408eSIcenowy Zheng .attach = anx78xx_bridge_attach, 1027885373dbSLyude Paul .detach = anx78xx_bridge_detach, 10285d97408eSIcenowy Zheng .mode_valid = anx78xx_bridge_mode_valid, 10295d97408eSIcenowy Zheng .disable = anx78xx_bridge_disable, 10305d97408eSIcenowy Zheng .mode_set = anx78xx_bridge_mode_set, 10315d97408eSIcenowy Zheng .enable = anx78xx_bridge_enable, 10325d97408eSIcenowy Zheng }; 10335d97408eSIcenowy Zheng 10345d97408eSIcenowy Zheng static irqreturn_t anx78xx_hpd_threaded_handler(int irq, void *data) 10355d97408eSIcenowy Zheng { 10365d97408eSIcenowy Zheng struct anx78xx *anx78xx = data; 10375d97408eSIcenowy Zheng int err; 10385d97408eSIcenowy Zheng 10395d97408eSIcenowy Zheng if (anx78xx->powered) 10405d97408eSIcenowy Zheng return IRQ_HANDLED; 10415d97408eSIcenowy Zheng 10425d97408eSIcenowy Zheng mutex_lock(&anx78xx->lock); 10435d97408eSIcenowy Zheng 10445d97408eSIcenowy Zheng /* Cable is pulled, power on the chip */ 10455d97408eSIcenowy Zheng anx78xx_poweron(anx78xx); 10465d97408eSIcenowy Zheng 10475d97408eSIcenowy Zheng err = anx78xx_enable_interrupts(anx78xx); 10485d97408eSIcenowy Zheng if (err) 10495d97408eSIcenowy Zheng DRM_ERROR("Failed to enable interrupts: %d\n", err); 10505d97408eSIcenowy Zheng 10515d97408eSIcenowy Zheng mutex_unlock(&anx78xx->lock); 10525d97408eSIcenowy Zheng 10535d97408eSIcenowy Zheng return IRQ_HANDLED; 10545d97408eSIcenowy Zheng } 10555d97408eSIcenowy Zheng 10565d97408eSIcenowy Zheng static int anx78xx_handle_dp_int_1(struct anx78xx *anx78xx, u8 irq) 10575d97408eSIcenowy Zheng { 10585d97408eSIcenowy Zheng int err; 10595d97408eSIcenowy Zheng 10605d97408eSIcenowy Zheng DRM_DEBUG_KMS("Handle DP interrupt 1: %02x\n", irq); 10615d97408eSIcenowy Zheng 10625d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], SP_DP_INT_STATUS1_REG, 10635d97408eSIcenowy Zheng irq); 10645d97408eSIcenowy Zheng if (err) 10655d97408eSIcenowy Zheng return err; 10665d97408eSIcenowy Zheng 10675d97408eSIcenowy Zheng if (irq & SP_TRAINING_FINISH) { 10685d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: hardware link training finished\n"); 10695d97408eSIcenowy Zheng err = anx78xx_config_dp_output(anx78xx); 10705d97408eSIcenowy Zheng } 10715d97408eSIcenowy Zheng 10725d97408eSIcenowy Zheng return err; 10735d97408eSIcenowy Zheng } 10745d97408eSIcenowy Zheng 10755d97408eSIcenowy Zheng static bool anx78xx_handle_common_int_4(struct anx78xx *anx78xx, u8 irq) 10765d97408eSIcenowy Zheng { 10775d97408eSIcenowy Zheng bool event = false; 10785d97408eSIcenowy Zheng int err; 10795d97408eSIcenowy Zheng 10805d97408eSIcenowy Zheng DRM_DEBUG_KMS("Handle common interrupt 4: %02x\n", irq); 10815d97408eSIcenowy Zheng 10825d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_TX_P2], 10835d97408eSIcenowy Zheng SP_COMMON_INT_STATUS4_REG, irq); 10845d97408eSIcenowy Zheng if (err) { 10855d97408eSIcenowy Zheng DRM_ERROR("Failed to write SP_COMMON_INT_STATUS4 %d\n", err); 10865d97408eSIcenowy Zheng return event; 10875d97408eSIcenowy Zheng } 10885d97408eSIcenowy Zheng 10895d97408eSIcenowy Zheng if (irq & SP_HPD_LOST) { 10905d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: Hot plug detect - cable is pulled out\n"); 10915d97408eSIcenowy Zheng event = true; 10925d97408eSIcenowy Zheng anx78xx_poweroff(anx78xx); 10935d97408eSIcenowy Zheng /* Free cached EDID */ 10945d97408eSIcenowy Zheng kfree(anx78xx->edid); 10955d97408eSIcenowy Zheng anx78xx->edid = NULL; 10965d97408eSIcenowy Zheng } else if (irq & SP_HPD_PLUG) { 10975d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: Hot plug detect - cable plug\n"); 10985d97408eSIcenowy Zheng event = true; 10995d97408eSIcenowy Zheng } 11005d97408eSIcenowy Zheng 11015d97408eSIcenowy Zheng return event; 11025d97408eSIcenowy Zheng } 11035d97408eSIcenowy Zheng 11045d97408eSIcenowy Zheng static void anx78xx_handle_hdmi_int_1(struct anx78xx *anx78xx, u8 irq) 11055d97408eSIcenowy Zheng { 11065d97408eSIcenowy Zheng unsigned int value; 11075d97408eSIcenowy Zheng int err; 11085d97408eSIcenowy Zheng 11095d97408eSIcenowy Zheng DRM_DEBUG_KMS("Handle HDMI interrupt 1: %02x\n", irq); 11105d97408eSIcenowy Zheng 11115d97408eSIcenowy Zheng err = regmap_write(anx78xx->map[I2C_IDX_RX_P0], SP_INT_STATUS1_REG, 11125d97408eSIcenowy Zheng irq); 11135d97408eSIcenowy Zheng if (err) { 11145d97408eSIcenowy Zheng DRM_ERROR("Write HDMI int 1 failed: %d\n", err); 11155d97408eSIcenowy Zheng return; 11165d97408eSIcenowy Zheng } 11175d97408eSIcenowy Zheng 11185d97408eSIcenowy Zheng if ((irq & SP_CKDT_CHG) || (irq & SP_SCDT_CHG)) { 11195d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: HDMI input detected\n"); 11205d97408eSIcenowy Zheng 11215d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_RX_P0], 11225d97408eSIcenowy Zheng SP_SYSTEM_STATUS_REG, &value); 11235d97408eSIcenowy Zheng if (err) { 11245d97408eSIcenowy Zheng DRM_ERROR("Read system status reg failed: %d\n", err); 11255d97408eSIcenowy Zheng return; 11265d97408eSIcenowy Zheng } 11275d97408eSIcenowy Zheng 11285d97408eSIcenowy Zheng if (!(value & SP_TMDS_CLOCK_DET)) { 11295d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: *** Waiting for HDMI clock ***\n"); 11305d97408eSIcenowy Zheng return; 11315d97408eSIcenowy Zheng } 11325d97408eSIcenowy Zheng 11335d97408eSIcenowy Zheng if (!(value & SP_TMDS_DE_DET)) { 11345d97408eSIcenowy Zheng DRM_DEBUG_KMS("IRQ: *** Waiting for HDMI signal ***\n"); 11355d97408eSIcenowy Zheng return; 11365d97408eSIcenowy Zheng } 11375d97408eSIcenowy Zheng 11385d97408eSIcenowy Zheng err = anx78xx_dp_link_training(anx78xx); 11395d97408eSIcenowy Zheng if (err) 11405d97408eSIcenowy Zheng DRM_ERROR("Failed to start link training: %d\n", err); 11415d97408eSIcenowy Zheng } 11425d97408eSIcenowy Zheng } 11435d97408eSIcenowy Zheng 11445d97408eSIcenowy Zheng static irqreturn_t anx78xx_intp_threaded_handler(int unused, void *data) 11455d97408eSIcenowy Zheng { 11465d97408eSIcenowy Zheng struct anx78xx *anx78xx = data; 11475d97408eSIcenowy Zheng bool event = false; 11485d97408eSIcenowy Zheng unsigned int irq; 11495d97408eSIcenowy Zheng int err; 11505d97408eSIcenowy Zheng 11515d97408eSIcenowy Zheng mutex_lock(&anx78xx->lock); 11525d97408eSIcenowy Zheng 11535d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_TX_P2], SP_DP_INT_STATUS1_REG, 11545d97408eSIcenowy Zheng &irq); 11555d97408eSIcenowy Zheng if (err) { 11565d97408eSIcenowy Zheng DRM_ERROR("Failed to read DP interrupt 1 status: %d\n", err); 11575d97408eSIcenowy Zheng goto unlock; 11585d97408eSIcenowy Zheng } 11595d97408eSIcenowy Zheng 11605d97408eSIcenowy Zheng if (irq) 11615d97408eSIcenowy Zheng anx78xx_handle_dp_int_1(anx78xx, irq); 11625d97408eSIcenowy Zheng 11635d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_TX_P2], 11645d97408eSIcenowy Zheng SP_COMMON_INT_STATUS4_REG, &irq); 11655d97408eSIcenowy Zheng if (err) { 11665d97408eSIcenowy Zheng DRM_ERROR("Failed to read common interrupt 4 status: %d\n", 11675d97408eSIcenowy Zheng err); 11685d97408eSIcenowy Zheng goto unlock; 11695d97408eSIcenowy Zheng } 11705d97408eSIcenowy Zheng 11715d97408eSIcenowy Zheng if (irq) 11725d97408eSIcenowy Zheng event = anx78xx_handle_common_int_4(anx78xx, irq); 11735d97408eSIcenowy Zheng 11745d97408eSIcenowy Zheng /* Make sure we are still powered after handle HPD events */ 11755d97408eSIcenowy Zheng if (!anx78xx->powered) 11765d97408eSIcenowy Zheng goto unlock; 11775d97408eSIcenowy Zheng 11785d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_RX_P0], SP_INT_STATUS1_REG, 11795d97408eSIcenowy Zheng &irq); 11805d97408eSIcenowy Zheng if (err) { 11815d97408eSIcenowy Zheng DRM_ERROR("Failed to read HDMI int 1 status: %d\n", err); 11825d97408eSIcenowy Zheng goto unlock; 11835d97408eSIcenowy Zheng } 11845d97408eSIcenowy Zheng 11855d97408eSIcenowy Zheng if (irq) 11865d97408eSIcenowy Zheng anx78xx_handle_hdmi_int_1(anx78xx, irq); 11875d97408eSIcenowy Zheng 11885d97408eSIcenowy Zheng unlock: 11895d97408eSIcenowy Zheng mutex_unlock(&anx78xx->lock); 11905d97408eSIcenowy Zheng 11915d97408eSIcenowy Zheng if (event) 11925d97408eSIcenowy Zheng drm_helper_hpd_irq_event(anx78xx->connector.dev); 11935d97408eSIcenowy Zheng 11945d97408eSIcenowy Zheng return IRQ_HANDLED; 11955d97408eSIcenowy Zheng } 11965d97408eSIcenowy Zheng 11975d97408eSIcenowy Zheng static void unregister_i2c_dummy_clients(struct anx78xx *anx78xx) 11985d97408eSIcenowy Zheng { 11995d97408eSIcenowy Zheng unsigned int i; 12005d97408eSIcenowy Zheng 12015d97408eSIcenowy Zheng for (i = 0; i < ARRAY_SIZE(anx78xx->i2c_dummy); i++) 12025d97408eSIcenowy Zheng i2c_unregister_device(anx78xx->i2c_dummy[i]); 12035d97408eSIcenowy Zheng } 12045d97408eSIcenowy Zheng 12055d97408eSIcenowy Zheng static const struct regmap_config anx78xx_regmap_config = { 12065d97408eSIcenowy Zheng .reg_bits = 8, 12075d97408eSIcenowy Zheng .val_bits = 8, 12085d97408eSIcenowy Zheng }; 12095d97408eSIcenowy Zheng 12105d97408eSIcenowy Zheng static const u16 anx78xx_chipid_list[] = { 12115d97408eSIcenowy Zheng 0x7808, 12125d97408eSIcenowy Zheng 0x7812, 12135d97408eSIcenowy Zheng 0x7814, 12145d97408eSIcenowy Zheng 0x7818, 12155d97408eSIcenowy Zheng }; 12165d97408eSIcenowy Zheng 12175d97408eSIcenowy Zheng static int anx78xx_i2c_probe(struct i2c_client *client, 12185d97408eSIcenowy Zheng const struct i2c_device_id *id) 12195d97408eSIcenowy Zheng { 12205d97408eSIcenowy Zheng struct anx78xx *anx78xx; 12215d97408eSIcenowy Zheng struct anx78xx_platform_data *pdata; 12225d97408eSIcenowy Zheng unsigned int i, idl, idh, version; 12235d97408eSIcenowy Zheng const u8 *i2c_addresses; 12245d97408eSIcenowy Zheng bool found = false; 12255d97408eSIcenowy Zheng int err; 12265d97408eSIcenowy Zheng 12275d97408eSIcenowy Zheng anx78xx = devm_kzalloc(&client->dev, sizeof(*anx78xx), GFP_KERNEL); 12285d97408eSIcenowy Zheng if (!anx78xx) 12295d97408eSIcenowy Zheng return -ENOMEM; 12305d97408eSIcenowy Zheng 12315d97408eSIcenowy Zheng pdata = &anx78xx->pdata; 12325d97408eSIcenowy Zheng 12335d97408eSIcenowy Zheng mutex_init(&anx78xx->lock); 12345d97408eSIcenowy Zheng 12355d97408eSIcenowy Zheng #if IS_ENABLED(CONFIG_OF) 12365d97408eSIcenowy Zheng anx78xx->bridge.of_node = client->dev.of_node; 12375d97408eSIcenowy Zheng #endif 12385d97408eSIcenowy Zheng 12395d97408eSIcenowy Zheng anx78xx->client = client; 12405d97408eSIcenowy Zheng i2c_set_clientdata(client, anx78xx); 12415d97408eSIcenowy Zheng 12425d97408eSIcenowy Zheng err = anx78xx_init_pdata(anx78xx); 12435d97408eSIcenowy Zheng if (err) { 12445d97408eSIcenowy Zheng if (err != -EPROBE_DEFER) 12455d97408eSIcenowy Zheng DRM_ERROR("Failed to initialize pdata: %d\n", err); 12465d97408eSIcenowy Zheng 12475d97408eSIcenowy Zheng return err; 12485d97408eSIcenowy Zheng } 12495d97408eSIcenowy Zheng 12505d97408eSIcenowy Zheng pdata->hpd_irq = gpiod_to_irq(pdata->gpiod_hpd); 12515d97408eSIcenowy Zheng if (pdata->hpd_irq < 0) { 12525d97408eSIcenowy Zheng DRM_ERROR("Failed to get HPD IRQ: %d\n", pdata->hpd_irq); 12535d97408eSIcenowy Zheng return -ENODEV; 12545d97408eSIcenowy Zheng } 12555d97408eSIcenowy Zheng 12565d97408eSIcenowy Zheng pdata->intp_irq = client->irq; 12575d97408eSIcenowy Zheng if (!pdata->intp_irq) { 12585d97408eSIcenowy Zheng DRM_ERROR("Failed to get CABLE_DET and INTP IRQ\n"); 12595d97408eSIcenowy Zheng return -ENODEV; 12605d97408eSIcenowy Zheng } 12615d97408eSIcenowy Zheng 12625d97408eSIcenowy Zheng /* Map slave addresses of ANX7814 */ 12635d97408eSIcenowy Zheng i2c_addresses = device_get_match_data(&client->dev); 12645d97408eSIcenowy Zheng for (i = 0; i < I2C_NUM_ADDRESSES; i++) { 12655d97408eSIcenowy Zheng struct i2c_client *i2c_dummy; 12665d97408eSIcenowy Zheng 12675d97408eSIcenowy Zheng i2c_dummy = i2c_new_dummy_device(client->adapter, 12685d97408eSIcenowy Zheng i2c_addresses[i] >> 1); 12695d97408eSIcenowy Zheng if (IS_ERR(i2c_dummy)) { 12705d97408eSIcenowy Zheng err = PTR_ERR(i2c_dummy); 12715d97408eSIcenowy Zheng DRM_ERROR("Failed to reserve I2C bus %02x: %d\n", 12725d97408eSIcenowy Zheng i2c_addresses[i], err); 12735d97408eSIcenowy Zheng goto err_unregister_i2c; 12745d97408eSIcenowy Zheng } 12755d97408eSIcenowy Zheng 12765d97408eSIcenowy Zheng anx78xx->i2c_dummy[i] = i2c_dummy; 12775d97408eSIcenowy Zheng anx78xx->map[i] = devm_regmap_init_i2c(anx78xx->i2c_dummy[i], 12785d97408eSIcenowy Zheng &anx78xx_regmap_config); 12795d97408eSIcenowy Zheng if (IS_ERR(anx78xx->map[i])) { 12805d97408eSIcenowy Zheng err = PTR_ERR(anx78xx->map[i]); 12815d97408eSIcenowy Zheng DRM_ERROR("Failed regmap initialization %02x\n", 12825d97408eSIcenowy Zheng i2c_addresses[i]); 12835d97408eSIcenowy Zheng goto err_unregister_i2c; 12845d97408eSIcenowy Zheng } 12855d97408eSIcenowy Zheng } 12865d97408eSIcenowy Zheng 12875d97408eSIcenowy Zheng /* Look for supported chip ID */ 12885d97408eSIcenowy Zheng anx78xx_poweron(anx78xx); 12895d97408eSIcenowy Zheng 12905d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_TX_P2], SP_DEVICE_IDL_REG, 12915d97408eSIcenowy Zheng &idl); 12925d97408eSIcenowy Zheng if (err) 12935d97408eSIcenowy Zheng goto err_poweroff; 12945d97408eSIcenowy Zheng 12955d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_TX_P2], SP_DEVICE_IDH_REG, 12965d97408eSIcenowy Zheng &idh); 12975d97408eSIcenowy Zheng if (err) 12985d97408eSIcenowy Zheng goto err_poweroff; 12995d97408eSIcenowy Zheng 13005d97408eSIcenowy Zheng anx78xx->chipid = (u8)idl | ((u8)idh << 8); 13015d97408eSIcenowy Zheng 13025d97408eSIcenowy Zheng err = regmap_read(anx78xx->map[I2C_IDX_TX_P2], SP_DEVICE_VERSION_REG, 13035d97408eSIcenowy Zheng &version); 13045d97408eSIcenowy Zheng if (err) 13055d97408eSIcenowy Zheng goto err_poweroff; 13065d97408eSIcenowy Zheng 13075d97408eSIcenowy Zheng for (i = 0; i < ARRAY_SIZE(anx78xx_chipid_list); i++) { 13085d97408eSIcenowy Zheng if (anx78xx->chipid == anx78xx_chipid_list[i]) { 13095d97408eSIcenowy Zheng DRM_INFO("Found ANX%x (ver. %d) SlimPort Transmitter\n", 13105d97408eSIcenowy Zheng anx78xx->chipid, version); 13115d97408eSIcenowy Zheng found = true; 13125d97408eSIcenowy Zheng break; 13135d97408eSIcenowy Zheng } 13145d97408eSIcenowy Zheng } 13155d97408eSIcenowy Zheng 13165d97408eSIcenowy Zheng if (!found) { 13175d97408eSIcenowy Zheng DRM_ERROR("ANX%x (ver. %d) not supported by this driver\n", 13185d97408eSIcenowy Zheng anx78xx->chipid, version); 13195d97408eSIcenowy Zheng err = -ENODEV; 13205d97408eSIcenowy Zheng goto err_poweroff; 13215d97408eSIcenowy Zheng } 13225d97408eSIcenowy Zheng 13235d97408eSIcenowy Zheng err = devm_request_threaded_irq(&client->dev, pdata->hpd_irq, NULL, 13245d97408eSIcenowy Zheng anx78xx_hpd_threaded_handler, 13255d97408eSIcenowy Zheng IRQF_TRIGGER_RISING | IRQF_ONESHOT, 13265d97408eSIcenowy Zheng "anx78xx-hpd", anx78xx); 13275d97408eSIcenowy Zheng if (err) { 13285d97408eSIcenowy Zheng DRM_ERROR("Failed to request CABLE_DET threaded IRQ: %d\n", 13295d97408eSIcenowy Zheng err); 13305d97408eSIcenowy Zheng goto err_poweroff; 13315d97408eSIcenowy Zheng } 13325d97408eSIcenowy Zheng 13335d97408eSIcenowy Zheng err = devm_request_threaded_irq(&client->dev, pdata->intp_irq, NULL, 13345d97408eSIcenowy Zheng anx78xx_intp_threaded_handler, 13355d97408eSIcenowy Zheng IRQF_TRIGGER_RISING | IRQF_ONESHOT, 13365d97408eSIcenowy Zheng "anx78xx-intp", anx78xx); 13375d97408eSIcenowy Zheng if (err) { 13385d97408eSIcenowy Zheng DRM_ERROR("Failed to request INTP threaded IRQ: %d\n", err); 13395d97408eSIcenowy Zheng goto err_poweroff; 13405d97408eSIcenowy Zheng } 13415d97408eSIcenowy Zheng 13425d97408eSIcenowy Zheng anx78xx->bridge.funcs = &anx78xx_bridge_funcs; 13435d97408eSIcenowy Zheng 13445d97408eSIcenowy Zheng drm_bridge_add(&anx78xx->bridge); 13455d97408eSIcenowy Zheng 13465d97408eSIcenowy Zheng /* If cable is pulled out, just poweroff and wait for HPD event */ 13475d97408eSIcenowy Zheng if (!gpiod_get_value(anx78xx->pdata.gpiod_hpd)) 13485d97408eSIcenowy Zheng anx78xx_poweroff(anx78xx); 13495d97408eSIcenowy Zheng 13505d97408eSIcenowy Zheng return 0; 13515d97408eSIcenowy Zheng 13525d97408eSIcenowy Zheng err_poweroff: 13535d97408eSIcenowy Zheng anx78xx_poweroff(anx78xx); 13545d97408eSIcenowy Zheng 13555d97408eSIcenowy Zheng err_unregister_i2c: 13565d97408eSIcenowy Zheng unregister_i2c_dummy_clients(anx78xx); 13575d97408eSIcenowy Zheng return err; 13585d97408eSIcenowy Zheng } 13595d97408eSIcenowy Zheng 1360*ed5c2f5fSUwe Kleine-König static void anx78xx_i2c_remove(struct i2c_client *client) 13615d97408eSIcenowy Zheng { 13625d97408eSIcenowy Zheng struct anx78xx *anx78xx = i2c_get_clientdata(client); 13635d97408eSIcenowy Zheng 13645d97408eSIcenowy Zheng drm_bridge_remove(&anx78xx->bridge); 13655d97408eSIcenowy Zheng 13665d97408eSIcenowy Zheng unregister_i2c_dummy_clients(anx78xx); 13675d97408eSIcenowy Zheng 13685d97408eSIcenowy Zheng kfree(anx78xx->edid); 13695d97408eSIcenowy Zheng } 13705d97408eSIcenowy Zheng 13715d97408eSIcenowy Zheng static const struct i2c_device_id anx78xx_id[] = { 13725d97408eSIcenowy Zheng { "anx7814", 0 }, 13735d97408eSIcenowy Zheng { /* sentinel */ } 13745d97408eSIcenowy Zheng }; 13755d97408eSIcenowy Zheng MODULE_DEVICE_TABLE(i2c, anx78xx_id); 13765d97408eSIcenowy Zheng 13775d97408eSIcenowy Zheng #if IS_ENABLED(CONFIG_OF) 13785d97408eSIcenowy Zheng static const struct of_device_id anx78xx_match_table[] = { 13795d97408eSIcenowy Zheng { .compatible = "analogix,anx7808", .data = anx7808_i2c_addresses }, 13805d97408eSIcenowy Zheng { .compatible = "analogix,anx7812", .data = anx781x_i2c_addresses }, 13815d97408eSIcenowy Zheng { .compatible = "analogix,anx7814", .data = anx781x_i2c_addresses }, 13825d97408eSIcenowy Zheng { .compatible = "analogix,anx7818", .data = anx781x_i2c_addresses }, 13835d97408eSIcenowy Zheng { /* sentinel */ }, 13845d97408eSIcenowy Zheng }; 13855d97408eSIcenowy Zheng MODULE_DEVICE_TABLE(of, anx78xx_match_table); 13865d97408eSIcenowy Zheng #endif 13875d97408eSIcenowy Zheng 13885d97408eSIcenowy Zheng static struct i2c_driver anx78xx_driver = { 13895d97408eSIcenowy Zheng .driver = { 13905d97408eSIcenowy Zheng .name = "anx7814", 13915d97408eSIcenowy Zheng .of_match_table = of_match_ptr(anx78xx_match_table), 13925d97408eSIcenowy Zheng }, 13935d97408eSIcenowy Zheng .probe = anx78xx_i2c_probe, 13945d97408eSIcenowy Zheng .remove = anx78xx_i2c_remove, 13955d97408eSIcenowy Zheng .id_table = anx78xx_id, 13965d97408eSIcenowy Zheng }; 13975d97408eSIcenowy Zheng module_i2c_driver(anx78xx_driver); 13985d97408eSIcenowy Zheng 13995d97408eSIcenowy Zheng MODULE_DESCRIPTION("ANX78xx SlimPort Transmitter driver"); 14005d97408eSIcenowy Zheng MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>"); 14015d97408eSIcenowy Zheng MODULE_LICENSE("GPL v2"); 1402