^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2018, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2019-2020. Linaro Limited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/hdmi-codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <drm/drm_atomic_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <drm/drm_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <drm/drm_mipi_dsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <drm/drm_probe_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define EDID_SEG_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define EDID_LEN 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define EDID_LOOP 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define KEY_DDC_ACCS_DONE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DDC_NO_ACK 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define LT9611_4LANES 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct lt9611 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct drm_bridge bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct drm_connector connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct device_node *dsi0_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct device_node *dsi1_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct mipi_dsi_device *dsi0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct mipi_dsi_device *dsi1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct platform_device *audio_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) bool ac_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct gpio_desc *enable_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bool power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) bool sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct regulator_bulk_data supplies[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) enum drm_connector_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 edid_buf[EDID_SEG_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 vic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define LT9611_PAGE_CONTROL 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const struct regmap_range_cfg lt9611_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .name = "register_range",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .range_min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .range_max = 0x85ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .selector_reg = LT9611_PAGE_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .selector_mask = 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .selector_shift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .window_start = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .window_len = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct regmap_config lt9611_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .max_register = 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .ranges = lt9611_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .num_ranges = ARRAY_SIZE(lt9611_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct lt9611_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u16 hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u16 vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 vrefresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u8 lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u8 intfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static struct lt9611_mode lt9611_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { 3840, 2160, 30, 4, 2 }, /* 3840x2160 24bit 30Hz 4Lane 2ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) { 1920, 1080, 24, 3, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) { 720, 480, 60, 4, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { 720, 576, 50, 2, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { 640, 480, 60, 2, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return container_of(bridge, struct lt9611, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct lt9611 *connector_to_lt9611(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return container_of(connector, struct lt9611, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct reg_sequence reg_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { 0x8106, 0x40 }, /* port A rx current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { 0x810a, 0xfe }, /* port A ldo voltage set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { 0x810b, 0xbf }, /* enable port A lprx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { 0x8111, 0x40 }, /* port B rx current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { 0x8115, 0xfe }, /* port B ldo voltage set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { 0x8116, 0xbf }, /* enable port B lprx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { 0x811c, 0x03 }, /* PortA clk lane no-LP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { 0x8120, 0x03 }, /* PortB clk lane with-LP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct reg_sequence reg_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { 0x8300, LT9611_4LANES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { 0x830a, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { 0x824f, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { 0x8250, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { 0x8302, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { 0x8306, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (mode->hdisplay == 3840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) reg_cfg[1].def = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u32 h_total, hactive, hsync_len, hfront_porch, hsync_porch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u32 v_total, vactive, vsync_len, vfront_porch, vsync_porch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) h_total = mode->htotal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) v_total = mode->vtotal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) hactive = mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hsync_len = mode->hsync_end - mode->hsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) hfront_porch = mode->hsync_start - mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) hsync_porch = hsync_len + mode->htotal - mode->hsync_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) vactive = mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) vsync_len = mode->vsync_end - mode->vsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) vfront_porch = mode->vsync_start - mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) vsync_porch = vsync_len + mode->vtotal - mode->vsync_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) regmap_write(lt9611->regmap, 0x830f, (u8)(vactive / 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) regmap_write(lt9611->regmap, 0x8310, (u8)(vactive % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) regmap_write(lt9611->regmap, 0x8311, (u8)(h_total / 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) regmap_write(lt9611->regmap, 0x8312, (u8)(h_total % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regmap_write(lt9611->regmap, 0x8313, (u8)(hactive / 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) regmap_write(lt9611->regmap, 0x8314, (u8)(hactive % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) regmap_write(lt9611->regmap, 0x8315, (u8)(vsync_len % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) regmap_write(lt9611->regmap, 0x8316, (u8)(hsync_len % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) regmap_write(lt9611->regmap, 0x8317, (u8)(vfront_porch % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) regmap_write(lt9611->regmap, 0x8318, (u8)(vsync_porch % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const struct reg_sequence reg_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { 0x830b, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { 0x830c, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { 0x8348, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { 0x8349, 0x81 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* stage 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) { 0x8321, 0x4a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) { 0x8324, 0x71 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) { 0x8325, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { 0x832a, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* stage 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { 0x834a, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { 0x831d, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* MK limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { 0x832d, 0x38 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { 0x8331, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) const struct reg_sequence reg_cfg2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { 0x830b, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { 0x830c, 0xd0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { 0x8348, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) { 0x8349, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { 0x8324, 0x72 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) { 0x8325, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { 0x832a, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { 0x834a, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { 0x831d, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { 0x8326, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) switch (mode->hdisplay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case 640:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) regmap_write(lt9611->regmap, 0x8326, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case 1920:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) regmap_write(lt9611->regmap, 0x8326, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case 3840:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* pcr rst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) regmap_write(lt9611->regmap, 0x8011, 0x5a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) regmap_write(lt9611->regmap, 0x8011, 0xfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int pclk = mode->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const struct reg_sequence reg_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* txpll init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { 0x8123, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 0x8124, 0x64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { 0x8125, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 0x8126, 0x55 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { 0x812c, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { 0x812f, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { 0x8126, 0x55 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { 0x8127, 0x66 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { 0x8128, 0x88 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (pclk > 150000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) regmap_write(lt9611->regmap, 0x812d, 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) else if (pclk > 70000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) regmap_write(lt9611->regmap, 0x812d, 0x99);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) regmap_write(lt9611->regmap, 0x812d, 0xaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * first divide pclk by 2 first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * - write divide by 64k to 19:16 bits which means shift by 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * - write divide by 256 to 15:8 bits which means shift by 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * - write remainder to 7:0 bits, which means shift by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) regmap_write(lt9611->regmap, 0x82e3, pclk >> 17); /* pclk[19:16] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) regmap_write(lt9611->regmap, 0x82e4, pclk >> 9); /* pclk[15:8] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) regmap_write(lt9611->regmap, 0x82e5, pclk >> 1); /* pclk[7:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) regmap_write(lt9611->regmap, 0x82de, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) regmap_write(lt9611->regmap, 0x82de, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) regmap_write(lt9611->regmap, 0x8016, 0xf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) regmap_write(lt9611->regmap, 0x8016, 0xf3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int lt9611_read_video_check(struct lt9611 *lt9611, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int temp, temp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = regmap_read(lt9611->regmap, reg, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) temp <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = regmap_read(lt9611->regmap, reg + 1, &temp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return (temp + temp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int lt9611_video_check(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u32 v_total, vactive, hactive_a, hactive_b, h_total_sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* top module video check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* vactive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) temp = lt9611_read_video_check(lt9611, 0x8282);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) vactive = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* v_total */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) temp = lt9611_read_video_check(lt9611, 0x826c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) v_total = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* h_total_sysclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) temp = lt9611_read_video_check(lt9611, 0x8286);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) h_total_sysclk = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* hactive_a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) temp = lt9611_read_video_check(lt9611, 0x8382);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) hactive_a = temp / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* hactive_b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) temp = lt9611_read_video_check(lt9611, 0x8386);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (temp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) hactive_b = temp / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) dev_info(lt9611->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "video check: hactive_a=%d, hactive_b=%d, vactive=%d, v_total=%d, h_total_sysclk=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) hactive_a, hactive_b, vactive, v_total, h_total_sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) dev_err(lt9611->dev, "read video check error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) regmap_write(lt9611->regmap, 0x82d6, 0x8c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) regmap_write(lt9611->regmap, 0x82d7, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static void lt9611_hdmi_tx_phy(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct reg_sequence reg_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { 0x8130, 0x6a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { 0x8131, 0x44 }, /* HDMI DC mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { 0x8132, 0x4a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { 0x8133, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) { 0x8134, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { 0x8135, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) { 0x8136, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { 0x8137, 0x44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) { 0x813f, 0x0f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) { 0x8140, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { 0x8141, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) { 0x8142, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) { 0x8143, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { 0x8144, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* HDMI AC mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (lt9611->ac_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) reg_cfg[2].def = 0x73;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static irqreturn_t lt9611_irq_thread_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct lt9611 *lt9611 = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned int irq_flag0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) unsigned int irq_flag3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) regmap_read(lt9611->regmap, 0x820f, &irq_flag3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) regmap_read(lt9611->regmap, 0x820c, &irq_flag0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* hpd changed low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (irq_flag3 & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) dev_info(lt9611->dev, "hdmi cable disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) regmap_write(lt9611->regmap, 0x8207, 0xbf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) regmap_write(lt9611->regmap, 0x8207, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* hpd changed high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (irq_flag3 & 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dev_info(lt9611->dev, "hdmi cable connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) regmap_write(lt9611->regmap, 0x8207, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) regmap_write(lt9611->regmap, 0x8207, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (irq_flag3 & 0xc0 && lt9611->bridge.dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) drm_kms_helper_hotplug_event(lt9611->bridge.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* video input changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (irq_flag0 & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dev_info(lt9611->dev, "video input changed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) regmap_write(lt9611->regmap, 0x829e, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) regmap_write(lt9611->regmap, 0x829e, 0xf7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) regmap_write(lt9611->regmap, 0x8204, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) regmap_write(lt9611->regmap, 0x8204, 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static void lt9611_enable_hpd_interrupts(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) regmap_read(lt9611->regmap, 0x8203, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) val &= ~0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) regmap_write(lt9611->regmap, 0x8203, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) regmap_write(lt9611->regmap, 0x8207, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static void lt9611_sleep_setup(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) const struct reg_sequence sleep_setup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { 0x8024, 0x76 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { 0x8023, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { 0x8157, 0x03 }, /* set addr pin as output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) { 0x8149, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) { 0x8151, 0x30 }, /* disable IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { 0x8102, 0x48 }, /* MIPI Rx power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) { 0x8123, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) { 0x8130, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) { 0x8100, 0x01 }, /* bandgap power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { 0x8101, 0x00 }, /* system clk power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) regmap_multi_reg_write(lt9611->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sleep_setup, ARRAY_SIZE(sleep_setup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) lt9611->sleep = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int lt9611_power_on(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) const struct reg_sequence seq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* LT9611_System_Init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) { 0x8101, 0x18 }, /* sel xtal clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* timer for frequency meter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) { 0x821b, 0x69 }, /* timer 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) { 0x821c, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) { 0x82cb, 0x69 }, /* timer 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) { 0x82cc, 0x78 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* irq init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) { 0x8251, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) { 0x8258, 0x0a }, /* hpd irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) { 0x8259, 0x80 }, /* hpd debounce width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) { 0x829e, 0xf7 }, /* video check irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* power consumption for work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) { 0x8004, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) { 0x8006, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) { 0x800a, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) { 0x800b, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) { 0x800d, 0xef },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) { 0x8011, 0xfa },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (lt9611->power_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret = regmap_multi_reg_write(lt9611->regmap, seq, ARRAY_SIZE(seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) lt9611->power_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int lt9611_power_off(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) lt9611->power_on = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static void lt9611_reset(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) gpiod_set_value_cansleep(lt9611->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) gpiod_set_value_cansleep(lt9611->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) gpiod_set_value_cansleep(lt9611->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static void lt9611_assert_5v(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!lt9611->enable_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) gpiod_set_value_cansleep(lt9611->enable_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int lt9611_regulator_init(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) lt9611->supplies[0].supply = "vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) lt9611->supplies[1].supply = "vcc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = devm_regulator_bulk_get(lt9611->dev, 2, lt9611->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return regulator_set_load(lt9611->supplies[0].consumer, 300000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static int lt9611_regulator_enable(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = regulator_enable(lt9611->supplies[0].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) usleep_range(1000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = regulator_enable(lt9611->supplies[1].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) regulator_disable(lt9611->supplies[0].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static struct lt9611_mode *lt9611_find_mode(const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) for (i = 0; i < ARRAY_SIZE(lt9611_modes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (lt9611_modes[i].hdisplay == mode->hdisplay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) lt9611_modes[i].vdisplay == mode->vdisplay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) lt9611_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return <9611_modes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* connector funcs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static enum drm_connector_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) lt9611_connector_detect(struct drm_connector *connector, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct lt9611 *lt9611 = connector_to_lt9611(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned int reg_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) regmap_read(lt9611->regmap, 0x825e, ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) connected = (reg_val & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) lt9611->status = connected ? connector_status_connected :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return lt9611->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int lt9611_read_edid(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) unsigned int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* memset to clear old buffer, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) memset(lt9611->edid_buf, 0, sizeof(lt9611->edid_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) regmap_write(lt9611->regmap, 0x8503, 0xc9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* 0xA0 is EDID device address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) regmap_write(lt9611->regmap, 0x8504, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* 0x00 is EDID offset address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) regmap_write(lt9611->regmap, 0x8505, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* length for read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) regmap_write(lt9611->regmap, 0x8506, EDID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) regmap_write(lt9611->regmap, 0x8514, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) for (i = 0; i < EDID_LOOP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* offset address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) regmap_write(lt9611->regmap, 0x8505, i * EDID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) regmap_write(lt9611->regmap, 0x8507, 0x36);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) regmap_write(lt9611->regmap, 0x8507, 0x31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) regmap_write(lt9611->regmap, 0x8507, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) regmap_read(lt9611->regmap, 0x8540, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (temp & KEY_DDC_ACCS_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) for (j = 0; j < EDID_LEN; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) regmap_read(lt9611->regmap, 0x8583, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) lt9611->edid_buf[i * EDID_LEN + j] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) } else if (temp & DDC_NO_ACK) { /* DDC No Ack or Abitration lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_err(lt9611->dev, "read edid failed: no ack\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) dev_err(lt9611->dev, "read edid failed: access not done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) regmap_write(lt9611->regmap, 0x8507, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) lt9611_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct lt9611 *lt9611 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (len > 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* supports up to 1 extension block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* TODO: add support for more extension blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (block > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (block == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = lt9611_read_edid(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dev_err(lt9611->dev, "edid read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) block %= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) memcpy(buf, lt9611->edid_buf + (block * 128), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int lt9611_connector_get_modes(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct lt9611 *lt9611 = connector_to_lt9611(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct edid *edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) lt9611_power_on(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) edid = drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) drm_connector_update_edid_property(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) count = drm_add_edid_modes(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) kfree(edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static enum drm_mode_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) lt9611_connector_mode_valid(struct drm_connector *connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return lt9611_mode ? MODE_OK : MODE_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* bridge funcs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void lt9611_bridge_enable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (lt9611_power_on(lt9611)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dev_err(lt9611->dev, "power on failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) lt9611_mipi_input_analog(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) lt9611_hdmi_tx_digital(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) lt9611_hdmi_tx_phy(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) lt9611_video_check(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* Enable HDMI output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) regmap_write(lt9611->regmap, 0x8130, 0xea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static void lt9611_bridge_disable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Disable HDMI output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dev_err(lt9611->dev, "video on failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (lt9611_power_off(lt9611)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dev_err(lt9611->dev, "power on failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) drm_connector_helper_funcs lt9611_bridge_connector_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) .get_modes = lt9611_connector_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .mode_valid = lt9611_connector_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) .fill_modes = drm_helper_probe_single_connector_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .detect = lt9611_connector_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .destroy = drm_connector_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .reset = drm_atomic_helper_connector_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct device_node *dsi_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct mipi_dsi_device *dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct mipi_dsi_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) host = of_find_mipi_dsi_host_by_node(dsi_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dev_err(lt9611->dev, "failed to find dsi host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return ERR_PTR(-EPROBE_DEFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dsi = mipi_dsi_device_register_full(host, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (IS_ERR(dsi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_err(lt9611->dev, "failed to create dsi device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dsi->lanes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dsi->format = MIPI_DSI_FMT_RGB888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) MIPI_DSI_MODE_VIDEO_HSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ret = mipi_dsi_attach(dsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dev_err(lt9611->dev, "failed to attach dsi to host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) mipi_dsi_device_unregister(dsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static void lt9611_bridge_detach(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (lt9611->dsi1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) mipi_dsi_detach(lt9611->dsi1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) mipi_dsi_device_unregister(lt9611->dsi1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) mipi_dsi_detach(lt9611->dsi0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) mipi_dsi_device_unregister(lt9611->dsi0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = drm_connector_init(bridge->dev, <9611->connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) <9611_bridge_connector_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) DRM_MODE_CONNECTOR_HDMIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) DRM_ERROR("Failed to initialize connector with drm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) drm_connector_helper_add(<9611->connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) <9611_bridge_connector_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) drm_connector_attach_encoder(<9611->connector, bridge->encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!bridge->encoder) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) DRM_ERROR("Parent encoder object not found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static int lt9611_bridge_attach(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) enum drm_bridge_attach_flags flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = lt9611_connector_init(bridge, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* Attach primary DSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (IS_ERR(lt9611->dsi0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return PTR_ERR(lt9611->dsi0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* Attach secondary DSI, if specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (lt9611->dsi1_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) lt9611->dsi1 = lt9611_attach_dsi(lt9611, lt9611->dsi1_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (IS_ERR(lt9611->dsi1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = PTR_ERR(lt9611->dsi1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) goto err_unregister_dsi0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) err_unregister_dsi0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) lt9611_bridge_detach(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) drm_connector_cleanup(<9611->connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) mipi_dsi_device_unregister(lt9611->dsi0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) const struct drm_display_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (!lt9611_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return MODE_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return MODE_PANEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return MODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!lt9611->sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) lt9611_reset(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) regmap_write(lt9611->regmap, 0x80ee, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) lt9611->sleep = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static void lt9611_bridge_post_disable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) lt9611_sleep_setup(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) const struct drm_display_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) const struct drm_display_mode *adj_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct hdmi_avi_infoframe avi_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) lt9611_bridge_pre_enable(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) lt9611_mipi_input_digital(lt9611, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) lt9611_pll_setup(lt9611, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) lt9611_mipi_video_setup(lt9611, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) lt9611_pcr_setup(lt9611, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) <9611->connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) lt9611->vic = avi_frame.video_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) unsigned int reg_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) regmap_read(lt9611->regmap, 0x825e, ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) connected = reg_val & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) lt9611->status = connected ? connector_status_connected :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return lt9611->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) lt9611_power_on(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) lt9611_enable_hpd_interrupts(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static const struct drm_bridge_funcs lt9611_bridge_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .attach = lt9611_bridge_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .detach = lt9611_bridge_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .mode_valid = lt9611_bridge_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .enable = lt9611_bridge_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .disable = lt9611_bridge_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .post_disable = lt9611_bridge_post_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .mode_set = lt9611_bridge_mode_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .detect = lt9611_bridge_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .get_edid = lt9611_bridge_get_edid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .hpd_enable = lt9611_bridge_hpd_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int lt9611_parse_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) lt9611->dsi0_node = of_graph_get_remote_node(dev->of_node, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (!lt9611->dsi0_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) dev_err(lt9611->dev, "failed to get remote node for primary dsi\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) lt9611->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) static int lt9611_gpio_init(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct device *dev = lt9611->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) lt9611->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (IS_ERR(lt9611->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) dev_err(dev, "failed to acquire reset gpio\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return PTR_ERR(lt9611->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) lt9611->enable_gpio = devm_gpiod_get_optional(dev, "enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (IS_ERR(lt9611->enable_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) dev_err(dev, "failed to acquire enable gpio\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return PTR_ERR(lt9611->enable_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int lt9611_read_device_rev(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned int rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) regmap_write(lt9611->regmap, 0x80ee, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ret = regmap_read(lt9611->regmap, 0x8002, &rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) dev_err(lt9611->dev, "failed to read revision: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dev_info(lt9611->dev, "LT9611 revision: 0x%x\n", rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int lt9611_hdmi_hw_params(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct hdmi_codec_daifmt *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct hdmi_codec_params *hparms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct lt9611 *lt9611 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (hparms->sample_rate == 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) regmap_write(lt9611->regmap, 0x840f, 0x2b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) else if (hparms->sample_rate == 96000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) regmap_write(lt9611->regmap, 0x840f, 0xab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) regmap_write(lt9611->regmap, 0x8435, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) regmap_write(lt9611->regmap, 0x8436, 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) regmap_write(lt9611->regmap, 0x8437, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) static int lt9611_audio_startup(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct lt9611 *lt9611 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) regmap_write(lt9611->regmap, 0x82d6, 0x8c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) regmap_write(lt9611->regmap, 0x82d7, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) regmap_write(lt9611->regmap, 0x8406, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) regmap_write(lt9611->regmap, 0x8407, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) regmap_write(lt9611->regmap, 0x8434, 0xd5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static void lt9611_audio_shutdown(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct lt9611 *lt9611 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) regmap_write(lt9611->regmap, 0x8406, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) regmap_write(lt9611->regmap, 0x8407, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct device_node *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct of_endpoint of_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ret = of_graph_parse_endpoint(endpoint, &of_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * HDMI sound should be located as reg = <2>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * Then, it is sound port 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (of_ep.port == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static const struct hdmi_codec_ops lt9611_codec_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .hw_params = lt9611_hdmi_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .audio_shutdown = lt9611_audio_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .audio_startup = lt9611_audio_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .get_dai_id = lt9611_hdmi_i2s_get_dai_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static struct hdmi_codec_pdata codec_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .ops = <9611_codec_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .max_i2s_channels = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .i2s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) codec_data.data = lt9611;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) lt9611->audio_pdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) PLATFORM_DEVID_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) &codec_data, sizeof(codec_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static void lt9611_audio_exit(struct lt9611 *lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (lt9611->audio_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) platform_device_unregister(lt9611->audio_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) lt9611->audio_pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static int lt9611_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct lt9611 *lt9611;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dev_err(dev, "device doesn't support I2C\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) lt9611 = devm_kzalloc(dev, sizeof(*lt9611), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!lt9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) lt9611->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) lt9611->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) lt9611->sleep = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) lt9611->regmap = devm_regmap_init_i2c(client, <9611_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (IS_ERR(lt9611->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dev_err(lt9611->dev, "regmap i2c init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return PTR_ERR(lt9611->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) ret = lt9611_parse_dt(&client->dev, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev_err(dev, "failed to parse device tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ret = lt9611_gpio_init(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) goto err_of_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) ret = lt9611_regulator_init(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) goto err_of_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) lt9611_assert_5v(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ret = lt9611_regulator_enable(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) goto err_of_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) lt9611_reset(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret = lt9611_read_device_rev(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) dev_err(dev, "failed to read chip rev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) goto err_disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ret = devm_request_threaded_irq(dev, client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) lt9611_irq_thread_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) IRQF_ONESHOT, "lt9611", lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev_err(dev, "failed to request irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto err_disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) i2c_set_clientdata(client, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) lt9611->bridge.funcs = <9611_bridge_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) lt9611->bridge.of_node = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) drm_bridge_add(<9611->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) lt9611_enable_hpd_interrupts(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return lt9611_audio_init(dev, lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) err_disable_regulators:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) err_of_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) of_node_put(lt9611->dsi1_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) of_node_put(lt9611->dsi0_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static int lt9611_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct lt9611 *lt9611 = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) disable_irq(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) lt9611_audio_exit(lt9611);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) drm_bridge_remove(<9611->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) of_node_put(lt9611->dsi1_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) of_node_put(lt9611->dsi0_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static struct i2c_device_id lt9611_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) { "lontium,lt9611", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) MODULE_DEVICE_TABLE(i2c, lt9611_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) static const struct of_device_id lt9611_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) { .compatible = "lontium,lt9611" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) MODULE_DEVICE_TABLE(of, lt9611_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static struct i2c_driver lt9611_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .name = "lt9611",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .of_match_table = lt9611_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) .probe = lt9611_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .remove = lt9611_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) .id_table = lt9611_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) module_i2c_driver(lt9611_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) MODULE_LICENSE("GPL v2");