Path: blob/master/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
26516 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Analog Devices ADV7511 HDMI transmitter driver3*4* Copyright 2012 Analog Devices Inc.5*/67#include <linux/clk.h>8#include <linux/device.h>9#include <linux/gpio/consumer.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/slab.h>1314#include <sound/pcm.h>1516#include <drm/drm_atomic.h>17#include <drm/drm_atomic_helper.h>18#include <drm/drm_bridge_connector.h>19#include <drm/drm_edid.h>20#include <drm/drm_of.h>21#include <drm/drm_print.h>22#include <drm/drm_probe_helper.h>23#include <drm/display/drm_hdmi_helper.h>24#include <drm/display/drm_hdmi_state_helper.h>2526#include "adv7511.h"2728/* ADI recommended values for proper operation. */29static const struct reg_sequence adv7511_fixed_registers[] = {30{ 0x98, 0x03 },31{ 0x9a, 0xe0 },32{ 0x9c, 0x30 },33{ 0x9d, 0x61 },34{ 0xa2, 0xa4 },35{ 0xa3, 0xa4 },36{ 0xe0, 0xd0 },37{ 0xf9, 0x00 },38{ 0x55, 0x02 },39};4041/* -----------------------------------------------------------------------------42* Register access43*/4445static const uint8_t adv7511_register_defaults[] = {460x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */470x00, 0x00, 0x01, 0x0e, 0xbc, 0x18, 0x01, 0x13,480x25, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */490x46, 0x62, 0x04, 0xa8, 0x00, 0x00, 0x1c, 0x84,500x1c, 0xbf, 0x04, 0xa8, 0x1e, 0x70, 0x02, 0x1e, /* 20 */510x00, 0x00, 0x04, 0xa8, 0x08, 0x12, 0x1b, 0xac,520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */530x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,540x00, 0x50, 0x90, 0x7e, 0x79, 0x70, 0x00, 0x00, /* 40 */550x00, 0xa8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,560x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, /* 50 */570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 */590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,600x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 */610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80 */630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,640x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 90 */650x0b, 0x02, 0x00, 0x18, 0x5a, 0x60, 0x00, 0x00,660x00, 0x00, 0x80, 0x80, 0x08, 0x04, 0x00, 0x00, /* a0 */670x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x14,680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0 */690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0 */710x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x01, 0x04,720x30, 0xff, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* d0 */730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,740x80, 0x75, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* e0 */750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,760x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, /* f0 */770x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,78};7980static bool adv7511_register_volatile(struct device *dev, unsigned int reg)81{82switch (reg) {83case ADV7511_REG_CHIP_REVISION:84case ADV7511_REG_SPDIF_FREQ:85case ADV7511_REG_CTS_AUTOMATIC1:86case ADV7511_REG_CTS_AUTOMATIC2:87case ADV7511_REG_VIC_DETECTED:88case ADV7511_REG_VIC_SEND:89case ADV7511_REG_AUX_VIC_DETECTED:90case ADV7511_REG_STATUS:91case ADV7511_REG_GC(1):92case ADV7511_REG_INT(0):93case ADV7511_REG_INT(1):94case ADV7511_REG_PLL_STATUS:95case ADV7511_REG_AN(0):96case ADV7511_REG_AN(1):97case ADV7511_REG_AN(2):98case ADV7511_REG_AN(3):99case ADV7511_REG_AN(4):100case ADV7511_REG_AN(5):101case ADV7511_REG_AN(6):102case ADV7511_REG_AN(7):103case ADV7511_REG_HDCP_STATUS:104case ADV7511_REG_BCAPS:105case ADV7511_REG_BKSV(0):106case ADV7511_REG_BKSV(1):107case ADV7511_REG_BKSV(2):108case ADV7511_REG_BKSV(3):109case ADV7511_REG_BKSV(4):110case ADV7511_REG_DDC_STATUS:111case ADV7511_REG_EDID_READ_CTRL:112case ADV7511_REG_BSTATUS(0):113case ADV7511_REG_BSTATUS(1):114case ADV7511_REG_CHIP_ID_HIGH:115case ADV7511_REG_CHIP_ID_LOW:116return true;117}118119return false;120}121122static const struct regmap_config adv7511_regmap_config = {123.reg_bits = 8,124.val_bits = 8,125126.max_register = 0xff,127.cache_type = REGCACHE_MAPLE,128.reg_defaults_raw = adv7511_register_defaults,129.num_reg_defaults_raw = ARRAY_SIZE(adv7511_register_defaults),130131.volatile_reg = adv7511_register_volatile,132};133134/* -----------------------------------------------------------------------------135* Hardware configuration136*/137138static void adv7511_set_colormap(struct adv7511 *adv7511, bool enable,139const uint16_t *coeff,140unsigned int scaling_factor)141{142unsigned int i;143144regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1),145ADV7511_CSC_UPDATE_MODE, ADV7511_CSC_UPDATE_MODE);146147if (enable) {148for (i = 0; i < 12; ++i) {149regmap_update_bits(adv7511->regmap,150ADV7511_REG_CSC_UPPER(i),1510x1f, coeff[i] >> 8);152regmap_write(adv7511->regmap,153ADV7511_REG_CSC_LOWER(i),154coeff[i] & 0xff);155}156}157158if (enable)159regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(0),1600xe0, 0x80 | (scaling_factor << 5));161else162regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(0),1630x80, 0x00);164165regmap_update_bits(adv7511->regmap, ADV7511_REG_CSC_UPPER(1),166ADV7511_CSC_UPDATE_MODE, 0);167}168169static int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet)170{171if (packet & 0xff)172regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,173packet, 0xff);174175if (packet & 0xff00) {176packet >>= 8;177regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1,178packet, 0xff);179}180181return 0;182}183184static int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet)185{186if (packet & 0xff)187regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,188packet, 0x00);189190if (packet & 0xff00) {191packet >>= 8;192regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1,193packet, 0x00);194}195196return 0;197}198199/* Coefficients for adv7511 color space conversion */200static const uint16_t adv7511_csc_ycbcr_to_rgb[] = {2010x0734, 0x04ad, 0x0000, 0x1c1b,2020x1ddc, 0x04ad, 0x1f24, 0x0135,2030x0000, 0x04ad, 0x087c, 0x1b77,204};205206static void adv7511_set_config_csc(struct adv7511 *adv7511,207struct drm_connector *connector,208bool rgb)209{210struct adv7511_video_config config;211bool output_format_422, output_format_ycbcr;212unsigned int mode;213214if (rgb) {215config.csc_enable = false;216output_format_422 = false;217output_format_ycbcr = false;218} else {219config.csc_scaling_factor = ADV7511_CSC_SCALING_4;220config.csc_coefficents = adv7511_csc_ycbcr_to_rgb;221222if ((connector->display_info.color_formats &223DRM_COLOR_FORMAT_YCBCR422) &&224connector->display_info.is_hdmi) {225config.csc_enable = false;226output_format_422 = true;227output_format_ycbcr = true;228} else {229config.csc_enable = true;230output_format_422 = false;231output_format_ycbcr = false;232}233}234235if (connector->display_info.is_hdmi)236mode = ADV7511_HDMI_CFG_MODE_HDMI;237else238mode = ADV7511_HDMI_CFG_MODE_DVI;239240adv7511_set_colormap(adv7511, config.csc_enable,241config.csc_coefficents,242config.csc_scaling_factor);243244regmap_update_bits(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG1, 0x81,245(output_format_422 << 7) | output_format_ycbcr);246247regmap_update_bits(adv7511->regmap, ADV7511_REG_HDCP_HDMI_CFG,248ADV7511_HDMI_CFG_MODE_MASK, mode);249}250251static void adv7511_set_link_config(struct adv7511 *adv7511,252const struct adv7511_link_config *config)253{254/*255* The input style values documented in the datasheet don't match the256* hardware register field values :-(257*/258static const unsigned int input_styles[4] = { 0, 2, 1, 3 };259260unsigned int clock_delay;261unsigned int color_depth;262unsigned int input_id;263264clock_delay = (config->clock_delay + 1200) / 400;265color_depth = config->input_color_depth == 8 ? 3266: (config->input_color_depth == 10 ? 1 : 2);267268/* TODO Support input ID 6 */269if (config->input_colorspace != HDMI_COLORSPACE_YUV422)270input_id = config->input_clock == ADV7511_INPUT_CLOCK_DDR271? 5 : 0;272else if (config->input_clock == ADV7511_INPUT_CLOCK_DDR)273input_id = config->embedded_sync ? 8 : 7;274else if (config->input_clock == ADV7511_INPUT_CLOCK_2X)275input_id = config->embedded_sync ? 4 : 3;276else277input_id = config->embedded_sync ? 2 : 1;278279regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, 0xf,280input_id);281regmap_update_bits(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG1, 0x7e,282(color_depth << 4) |283(input_styles[config->input_style] << 2));284regmap_write(adv7511->regmap, ADV7511_REG_VIDEO_INPUT_CFG2,285config->input_justification << 3);286regmap_write(adv7511->regmap, ADV7511_REG_TIMING_GEN_SEQ,287config->sync_pulse << 2);288289regmap_write(adv7511->regmap, 0xba, clock_delay << 5);290291adv7511->embedded_sync = config->embedded_sync;292adv7511->hsync_polarity = config->hsync_polarity;293adv7511->vsync_polarity = config->vsync_polarity;294adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;295}296297static void __adv7511_power_on(struct adv7511 *adv7511)298{299adv7511->current_edid_segment = -1;300301regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,302ADV7511_POWER_POWER_DOWN, 0);303if (adv7511->i2c_main->irq) {304/*305* Documentation says the INT_ENABLE registers are reset in306* POWER_DOWN mode. My 7511w preserved the bits, however.307* Still, let's be safe and stick to the documentation.308*/309regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),310ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);311regmap_update_bits(adv7511->regmap,312ADV7511_REG_INT_ENABLE(1),313ADV7511_INT1_DDC_ERROR,314ADV7511_INT1_DDC_ERROR);315}316317/*318* Per spec it is allowed to pulse the HPD signal to indicate that the319* EDID information has changed. Some monitors do this when they wakeup320* from standby or are enabled. When the HPD goes low the adv7511 is321* reset and the outputs are disabled which might cause the monitor to322* go to standby again. To avoid this we ignore the HPD pin for the323* first few seconds after enabling the output. On the other hand324* adv7535 require to enable HPD Override bit for proper HPD.325*/326if (adv7511->info->hpd_override_enable)327regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,328ADV7535_REG_POWER2_HPD_OVERRIDE,329ADV7535_REG_POWER2_HPD_OVERRIDE);330else331regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,332ADV7511_REG_POWER2_HPD_SRC_MASK,333ADV7511_REG_POWER2_HPD_SRC_NONE);334}335336static void adv7511_power_on(struct adv7511 *adv7511)337{338__adv7511_power_on(adv7511);339340/*341* Most of the registers are reset during power down or when HPD is low.342*/343regcache_sync(adv7511->regmap);344345if (adv7511->info->has_dsi)346adv7533_dsi_power_on(adv7511);347adv7511->powered = true;348}349350static void __adv7511_power_off(struct adv7511 *adv7511)351{352/* TODO: setup additional power down modes */353if (adv7511->info->hpd_override_enable)354regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,355ADV7535_REG_POWER2_HPD_OVERRIDE, 0);356357regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,358ADV7511_POWER_POWER_DOWN,359ADV7511_POWER_POWER_DOWN);360regmap_update_bits(adv7511->regmap,361ADV7511_REG_INT_ENABLE(1),362ADV7511_INT1_DDC_ERROR, 0);363regcache_mark_dirty(adv7511->regmap);364}365366static void adv7511_power_off(struct adv7511 *adv7511)367{368__adv7511_power_off(adv7511);369if (adv7511->info->has_dsi)370adv7533_dsi_power_off(adv7511);371adv7511->powered = false;372}373374/* -----------------------------------------------------------------------------375* Interrupt and hotplug detection376*/377378static bool adv7511_hpd(struct adv7511 *adv7511)379{380unsigned int irq0;381int ret;382383ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);384if (ret < 0)385return false;386387if (irq0 & ADV7511_INT0_HPD) {388regmap_write(adv7511->regmap, ADV7511_REG_INT(0),389ADV7511_INT0_HPD);390return true;391}392393return false;394}395396static void adv7511_hpd_work(struct work_struct *work)397{398struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);399enum drm_connector_status status;400unsigned int val;401int ret;402403ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);404if (ret < 0)405status = connector_status_disconnected;406else if (val & ADV7511_STATUS_HPD)407status = connector_status_connected;408else409status = connector_status_disconnected;410411/*412* The bridge resets its registers on unplug. So when we get a plug413* event and we're already supposed to be powered, cycle the bridge to414* restore its state.415*/416if (status == connector_status_connected &&417adv7511->status == connector_status_disconnected &&418adv7511->powered) {419regcache_mark_dirty(adv7511->regmap);420adv7511_power_on(adv7511);421}422423if (adv7511->status != status) {424adv7511->status = status;425426drm_bridge_hpd_notify(&adv7511->bridge, status);427}428}429430static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)431{432unsigned int irq0, irq1;433int ret;434int cec_status = IRQ_NONE;435int irq_status = IRQ_NONE;436437ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);438if (ret < 0)439return ret;440441ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1);442if (ret < 0)443return ret;444445regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);446regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);447448if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder) {449schedule_work(&adv7511->hpd_work);450irq_status = IRQ_HANDLED;451}452453if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {454adv7511->edid_read = true;455456if (adv7511->i2c_main->irq)457wake_up_all(&adv7511->wq);458irq_status = IRQ_HANDLED;459}460461#ifdef CONFIG_DRM_I2C_ADV7511_CEC462cec_status = adv7511_cec_irq_process(adv7511, irq1);463#endif464465/* If there is no IRQ to handle, exit indicating no IRQ data */466if (irq_status == IRQ_HANDLED || cec_status == IRQ_HANDLED)467return IRQ_HANDLED;468469return IRQ_NONE;470}471472static irqreturn_t adv7511_irq_handler(int irq, void *devid)473{474struct adv7511 *adv7511 = devid;475int ret;476477ret = adv7511_irq_process(adv7511, true);478return ret < 0 ? IRQ_NONE : ret;479}480481/* -----------------------------------------------------------------------------482* EDID retrieval483*/484485static int adv7511_wait_for_edid(struct adv7511 *adv7511, int timeout)486{487int ret;488489if (adv7511->i2c_main->irq) {490ret = wait_event_interruptible_timeout(adv7511->wq,491adv7511->edid_read, msecs_to_jiffies(timeout));492} else {493for (; timeout > 0; timeout -= 25) {494ret = adv7511_irq_process(adv7511, false);495if (ret < 0)496break;497498if (adv7511->edid_read)499break;500501msleep(25);502}503}504505return adv7511->edid_read ? 0 : -EIO;506}507508static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,509size_t len)510{511struct adv7511 *adv7511 = data;512struct i2c_msg xfer[2];513uint8_t offset;514unsigned int i;515int ret;516517if (len > 128)518return -EINVAL;519520if (adv7511->current_edid_segment != block / 2) {521unsigned int status;522523ret = regmap_read(adv7511->regmap, ADV7511_REG_DDC_STATUS,524&status);525if (ret < 0)526return ret;527528if (status != 2) {529adv7511->edid_read = false;530regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,531block);532ret = adv7511_wait_for_edid(adv7511, 200);533if (ret < 0)534return ret;535}536537/* Break this apart, hopefully more I2C controllers will538* support 64 byte transfers than 256 byte transfers539*/540541xfer[0].addr = adv7511->i2c_edid->addr;542xfer[0].flags = 0;543xfer[0].len = 1;544xfer[0].buf = &offset;545xfer[1].addr = adv7511->i2c_edid->addr;546xfer[1].flags = I2C_M_RD;547xfer[1].len = 64;548xfer[1].buf = adv7511->edid_buf;549550offset = 0;551552for (i = 0; i < 4; ++i) {553ret = i2c_transfer(adv7511->i2c_edid->adapter, xfer,554ARRAY_SIZE(xfer));555if (ret < 0)556return ret;557else if (ret != 2)558return -EIO;559560xfer[1].buf += 64;561offset += 64;562}563564adv7511->current_edid_segment = block / 2;565}566567if (block % 2 == 0)568memcpy(buf, adv7511->edid_buf, len);569else570memcpy(buf, adv7511->edid_buf + 128, len);571572return 0;573}574575/* -----------------------------------------------------------------------------576* ADV75xx helpers577*/578579static const struct drm_edid *adv7511_edid_read(struct adv7511 *adv7511,580struct drm_connector *connector)581{582const struct drm_edid *drm_edid;583584/* Reading the EDID only works if the device is powered */585if (!adv7511->powered) {586unsigned int edid_i2c_addr =587(adv7511->i2c_edid->addr << 1);588589__adv7511_power_on(adv7511);590591/* Reset the EDID_I2C_ADDR register as it might be cleared */592regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,593edid_i2c_addr);594}595596drm_edid = drm_edid_read_custom(connector, adv7511_get_edid_block, adv7511);597598if (!adv7511->powered)599__adv7511_power_off(adv7511);600601return drm_edid;602}603604static enum drm_connector_status605adv7511_detect(struct adv7511 *adv7511)606{607enum drm_connector_status status;608unsigned int val;609bool hpd;610int ret;611612ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);613if (ret < 0)614return connector_status_disconnected;615616if (val & ADV7511_STATUS_HPD)617status = connector_status_connected;618else619status = connector_status_disconnected;620621hpd = adv7511_hpd(adv7511);622623/* The chip resets itself when the cable is disconnected, so in case624* there is a pending HPD interrupt and the cable is connected there was625* at least one transition from disconnected to connected and the chip626* has to be reinitialized. */627if (status == connector_status_connected && hpd && adv7511->powered) {628regcache_mark_dirty(adv7511->regmap);629adv7511_power_on(adv7511);630if (adv7511->status == connector_status_connected)631status = connector_status_disconnected;632} else {633/* Renable HPD sensing */634if (adv7511->info->hpd_override_enable)635regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,636ADV7535_REG_POWER2_HPD_OVERRIDE,637ADV7535_REG_POWER2_HPD_OVERRIDE);638else639regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,640ADV7511_REG_POWER2_HPD_SRC_MASK,641ADV7511_REG_POWER2_HPD_SRC_BOTH);642}643644adv7511->status = status;645return status;646}647648static void adv7511_mode_set(struct adv7511 *adv7511,649const struct drm_display_mode *adj_mode)650{651unsigned int low_refresh_rate;652unsigned int hsync_polarity = 0;653unsigned int vsync_polarity = 0;654655if (adv7511->embedded_sync) {656unsigned int hsync_offset, hsync_len;657unsigned int vsync_offset, vsync_len;658659hsync_offset = adj_mode->crtc_hsync_start -660adj_mode->crtc_hdisplay;661vsync_offset = adj_mode->crtc_vsync_start -662adj_mode->crtc_vdisplay;663hsync_len = adj_mode->crtc_hsync_end -664adj_mode->crtc_hsync_start;665vsync_len = adj_mode->crtc_vsync_end -666adj_mode->crtc_vsync_start;667668/* The hardware vsync generator has a off-by-one bug */669vsync_offset += 1;670671regmap_write(adv7511->regmap, ADV7511_REG_HSYNC_PLACEMENT_MSB,672((hsync_offset >> 10) & 0x7) << 5);673regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(0),674(hsync_offset >> 2) & 0xff);675regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(1),676((hsync_offset & 0x3) << 6) |677((hsync_len >> 4) & 0x3f));678regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(2),679((hsync_len & 0xf) << 4) |680((vsync_offset >> 6) & 0xf));681regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(3),682((vsync_offset & 0x3f) << 2) |683((vsync_len >> 8) & 0x3));684regmap_write(adv7511->regmap, ADV7511_REG_SYNC_DECODER(4),685vsync_len & 0xff);686687hsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PHSYNC);688vsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PVSYNC);689} else {690enum adv7511_sync_polarity mode_hsync_polarity;691enum adv7511_sync_polarity mode_vsync_polarity;692693/**694* If the input signal is always low or always high we want to695* invert or let it passthrough depending on the polarity of the696* current mode.697**/698if (adj_mode->flags & DRM_MODE_FLAG_NHSYNC)699mode_hsync_polarity = ADV7511_SYNC_POLARITY_LOW;700else701mode_hsync_polarity = ADV7511_SYNC_POLARITY_HIGH;702703if (adj_mode->flags & DRM_MODE_FLAG_NVSYNC)704mode_vsync_polarity = ADV7511_SYNC_POLARITY_LOW;705else706mode_vsync_polarity = ADV7511_SYNC_POLARITY_HIGH;707708if (adv7511->hsync_polarity != mode_hsync_polarity &&709adv7511->hsync_polarity !=710ADV7511_SYNC_POLARITY_PASSTHROUGH)711hsync_polarity = 1;712713if (adv7511->vsync_polarity != mode_vsync_polarity &&714adv7511->vsync_polarity !=715ADV7511_SYNC_POLARITY_PASSTHROUGH)716vsync_polarity = 1;717}718719if (drm_mode_vrefresh(adj_mode) <= 24)720low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ;721else if (drm_mode_vrefresh(adj_mode) <= 25)722low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ;723else if (drm_mode_vrefresh(adj_mode) <= 30)724low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ;725else726low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;727728if (adv7511->info->type == ADV7511)729regmap_update_bits(adv7511->regmap, 0xfb,7300x6, low_refresh_rate << 1);731else732regmap_update_bits(adv7511->regmap, 0x4a,7330xc, low_refresh_rate << 2);734735regmap_update_bits(adv7511->regmap, 0x17,7360x60, (vsync_polarity << 6) | (hsync_polarity << 5));737738drm_mode_copy(&adv7511->curr_mode, adj_mode);739740/* Update horizontal/vertical porch params */741if (adv7511->info->has_dsi && adv7511->use_timing_gen)742adv7533_dsi_config_timing_gen(adv7511);743744/*745* TODO Test first order 4:2:2 to 4:4:4 up conversion method, which is746* supposed to give better results.747*/748749adv7511->f_tmds = adj_mode->clock;750}751752static int adv7511_connector_init(struct adv7511 *adv)753{754struct drm_bridge *bridge = &adv->bridge;755struct drm_connector *connector;756757connector = drm_bridge_connector_init(bridge->dev, bridge->encoder);758if (IS_ERR(connector)) {759DRM_ERROR("Failed to initialize connector with drm\n");760return PTR_ERR(connector);761}762763drm_connector_attach_encoder(connector, bridge->encoder);764765return 0;766}767768/* -----------------------------------------------------------------------------769* DRM Bridge Operations770*/771772static const struct adv7511 *bridge_to_adv7511_const(const struct drm_bridge *bridge)773{774return container_of(bridge, struct adv7511, bridge);775}776777static void adv7511_bridge_atomic_enable(struct drm_bridge *bridge,778struct drm_atomic_state *state)779{780struct adv7511 *adv = bridge_to_adv7511(bridge);781struct drm_connector *connector;782struct drm_connector_state *conn_state;783struct drm_crtc_state *crtc_state;784785adv7511_power_on(adv);786787connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);788if (WARN_ON(!connector))789return;790791conn_state = drm_atomic_get_new_connector_state(state, connector);792if (WARN_ON(!conn_state))793return;794795crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);796if (WARN_ON(!crtc_state))797return;798799adv7511_set_config_csc(adv, connector, adv->rgb);800801adv7511_mode_set(adv, &crtc_state->adjusted_mode);802803drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);804}805806static void adv7511_bridge_atomic_disable(struct drm_bridge *bridge,807struct drm_atomic_state *state)808{809struct adv7511 *adv = bridge_to_adv7511(bridge);810811adv7511_power_off(adv);812}813814static enum drm_mode_status815adv7511_bridge_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge,816const struct drm_display_mode *mode,817unsigned long long tmds_rate)818{819const struct adv7511 *adv = bridge_to_adv7511_const(bridge);820821if (tmds_rate > 1000ULL * adv->info->max_mode_clock_khz)822return MODE_CLOCK_HIGH;823824return MODE_OK;825}826827static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,828const struct drm_display_info *info,829const struct drm_display_mode *mode)830{831struct adv7511 *adv = bridge_to_adv7511(bridge);832833if (!adv->info->has_dsi)834return MODE_OK;835836return adv7533_mode_valid(adv, mode);837}838839static int adv7511_bridge_attach(struct drm_bridge *bridge,840struct drm_encoder *encoder,841enum drm_bridge_attach_flags flags)842{843struct adv7511 *adv = bridge_to_adv7511(bridge);844int ret = 0;845846if (adv->next_bridge) {847ret = drm_bridge_attach(encoder, adv->next_bridge, bridge,848flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);849if (ret)850return ret;851}852853if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {854ret = adv7511_connector_init(adv);855if (ret < 0)856return ret;857}858859if (adv->i2c_main->irq)860regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0),861ADV7511_INT0_HPD);862863return ret;864}865866static enum drm_connector_status867adv7511_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)868{869struct adv7511 *adv = bridge_to_adv7511(bridge);870871return adv7511_detect(adv);872}873874static const struct drm_edid *adv7511_bridge_edid_read(struct drm_bridge *bridge,875struct drm_connector *connector)876{877struct adv7511 *adv = bridge_to_adv7511(bridge);878879return adv7511_edid_read(adv, connector);880}881882static int adv7511_bridge_hdmi_clear_infoframe(struct drm_bridge *bridge,883enum hdmi_infoframe_type type)884{885struct adv7511 *adv7511 = bridge_to_adv7511(bridge);886887switch (type) {888case HDMI_INFOFRAME_TYPE_AVI:889adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME);890break;891default:892drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type);893break;894}895896return 0;897}898899static int adv7511_bridge_hdmi_write_infoframe(struct drm_bridge *bridge,900enum hdmi_infoframe_type type,901const u8 *buffer, size_t len)902{903struct adv7511 *adv7511 = bridge_to_adv7511(bridge);904905adv7511_bridge_hdmi_clear_infoframe(bridge, type);906907switch (type) {908case HDMI_INFOFRAME_TYPE_AVI:909/* The AVI infoframe id is not configurable */910regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION,911buffer + 1, len - 1);912913adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME);914break;915default:916drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type);917break;918}919920return 0;921}922923static const struct drm_bridge_funcs adv7511_bridge_funcs = {924.mode_valid = adv7511_bridge_mode_valid,925.attach = adv7511_bridge_attach,926.detect = adv7511_bridge_detect,927.edid_read = adv7511_bridge_edid_read,928929.atomic_enable = adv7511_bridge_atomic_enable,930.atomic_disable = adv7511_bridge_atomic_disable,931.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,932.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,933.atomic_reset = drm_atomic_helper_bridge_reset,934935.hdmi_tmds_char_rate_valid = adv7511_bridge_hdmi_tmds_char_rate_valid,936.hdmi_clear_infoframe = adv7511_bridge_hdmi_clear_infoframe,937.hdmi_write_infoframe = adv7511_bridge_hdmi_write_infoframe,938939.hdmi_audio_startup = adv7511_hdmi_audio_startup,940.hdmi_audio_prepare = adv7511_hdmi_audio_prepare,941.hdmi_audio_shutdown = adv7511_hdmi_audio_shutdown,942943.hdmi_cec_init = adv7511_cec_init,944.hdmi_cec_enable = adv7511_cec_enable,945.hdmi_cec_log_addr = adv7511_cec_log_addr,946.hdmi_cec_transmit = adv7511_cec_transmit,947};948949/* -----------------------------------------------------------------------------950* Probe & remove951*/952953static const char * const adv7511_supply_names[] = {954"avdd",955"dvdd",956"pvdd",957"bgvdd",958"dvdd-3v",959};960961static const char * const adv7533_supply_names[] = {962"avdd",963"dvdd",964"pvdd",965"a2vdd",966"v3p3",967"v1p2",968};969970static int adv7511_init_regulators(struct adv7511 *adv)971{972const char * const *supply_names = adv->info->supply_names;973unsigned int num_supplies = adv->info->num_supplies;974struct device *dev = &adv->i2c_main->dev;975unsigned int i;976int ret;977978adv->supplies = devm_kcalloc(dev, num_supplies,979sizeof(*adv->supplies), GFP_KERNEL);980if (!adv->supplies)981return -ENOMEM;982983for (i = 0; i < num_supplies; i++)984adv->supplies[i].supply = supply_names[i];985986ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies);987if (ret)988return ret;989990return regulator_bulk_enable(num_supplies, adv->supplies);991}992993static void adv7511_uninit_regulators(struct adv7511 *adv)994{995regulator_bulk_disable(adv->info->num_supplies, adv->supplies);996}997998static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg)999{1000struct i2c_client *i2c = to_i2c_client(dev);1001struct adv7511 *adv7511 = i2c_get_clientdata(i2c);10021003reg -= adv7511->info->reg_cec_offset;10041005switch (reg) {1006case ADV7511_REG_CEC_RX1_FRAME_HDR:1007case ADV7511_REG_CEC_RX1_FRAME_DATA0 ... ADV7511_REG_CEC_RX1_FRAME_DATA0 + 14:1008case ADV7511_REG_CEC_RX1_FRAME_LEN:1009case ADV7511_REG_CEC_RX2_FRAME_HDR:1010case ADV7511_REG_CEC_RX2_FRAME_DATA0 ... ADV7511_REG_CEC_RX2_FRAME_DATA0 + 14:1011case ADV7511_REG_CEC_RX2_FRAME_LEN:1012case ADV7511_REG_CEC_RX3_FRAME_HDR:1013case ADV7511_REG_CEC_RX3_FRAME_DATA0 ... ADV7511_REG_CEC_RX3_FRAME_DATA0 + 14:1014case ADV7511_REG_CEC_RX3_FRAME_LEN:1015case ADV7511_REG_CEC_RX_STATUS:1016case ADV7511_REG_CEC_RX_BUFFERS:1017case ADV7511_REG_CEC_TX_LOW_DRV_CNT:1018return true;1019}10201021return false;1022}10231024static const struct regmap_config adv7511_cec_regmap_config = {1025.reg_bits = 8,1026.val_bits = 8,10271028.max_register = 0xff,1029.cache_type = REGCACHE_MAPLE,1030.volatile_reg = adv7511_cec_register_volatile,1031};10321033static int adv7511_init_cec_regmap(struct adv7511 *adv)1034{1035int ret;10361037adv->i2c_cec = i2c_new_ancillary_device(adv->i2c_main, "cec",1038ADV7511_CEC_I2C_ADDR_DEFAULT);1039if (IS_ERR(adv->i2c_cec))1040return PTR_ERR(adv->i2c_cec);10411042regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR,1043adv->i2c_cec->addr << 1);10441045i2c_set_clientdata(adv->i2c_cec, adv);10461047adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,1048&adv7511_cec_regmap_config);1049if (IS_ERR(adv->regmap_cec)) {1050ret = PTR_ERR(adv->regmap_cec);1051goto err;1052}10531054if (adv->info->reg_cec_offset == ADV7533_REG_CEC_OFFSET) {1055ret = adv7533_patch_cec_registers(adv);1056if (ret)1057goto err;1058}10591060return 0;1061err:1062i2c_unregister_device(adv->i2c_cec);1063return ret;1064}10651066static int adv7511_parse_dt(struct device_node *np,1067struct adv7511_link_config *config)1068{1069const char *str;1070int ret;10711072of_property_read_u32(np, "adi,input-depth", &config->input_color_depth);1073if (config->input_color_depth != 8 && config->input_color_depth != 10 &&1074config->input_color_depth != 12)1075return -EINVAL;10761077ret = of_property_read_string(np, "adi,input-colorspace", &str);1078if (ret < 0)1079return ret;10801081if (!strcmp(str, "rgb"))1082config->input_colorspace = HDMI_COLORSPACE_RGB;1083else if (!strcmp(str, "yuv422"))1084config->input_colorspace = HDMI_COLORSPACE_YUV422;1085else if (!strcmp(str, "yuv444"))1086config->input_colorspace = HDMI_COLORSPACE_YUV444;1087else1088return -EINVAL;10891090ret = of_property_read_string(np, "adi,input-clock", &str);1091if (ret < 0)1092return ret;10931094if (!strcmp(str, "1x"))1095config->input_clock = ADV7511_INPUT_CLOCK_1X;1096else if (!strcmp(str, "2x"))1097config->input_clock = ADV7511_INPUT_CLOCK_2X;1098else if (!strcmp(str, "ddr"))1099config->input_clock = ADV7511_INPUT_CLOCK_DDR;1100else1101return -EINVAL;11021103if (config->input_colorspace == HDMI_COLORSPACE_YUV422 ||1104config->input_clock != ADV7511_INPUT_CLOCK_1X) {1105ret = of_property_read_u32(np, "adi,input-style",1106&config->input_style);1107if (ret)1108return ret;11091110if (config->input_style < 1 || config->input_style > 3)1111return -EINVAL;11121113ret = of_property_read_string(np, "adi,input-justification",1114&str);1115if (ret < 0)1116return ret;11171118if (!strcmp(str, "left"))1119config->input_justification =1120ADV7511_INPUT_JUSTIFICATION_LEFT;1121else if (!strcmp(str, "evenly"))1122config->input_justification =1123ADV7511_INPUT_JUSTIFICATION_EVENLY;1124else if (!strcmp(str, "right"))1125config->input_justification =1126ADV7511_INPUT_JUSTIFICATION_RIGHT;1127else1128return -EINVAL;11291130} else {1131config->input_style = 1;1132config->input_justification = ADV7511_INPUT_JUSTIFICATION_LEFT;1133}11341135of_property_read_u32(np, "adi,clock-delay", &config->clock_delay);1136if (config->clock_delay < -1200 || config->clock_delay > 1600)1137return -EINVAL;11381139config->embedded_sync = of_property_read_bool(np, "adi,embedded-sync");11401141/* Hardcode the sync pulse configurations for now. */1142config->sync_pulse = ADV7511_INPUT_SYNC_PULSE_NONE;1143config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;1144config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;11451146return 0;1147}11481149static int adv7511_probe(struct i2c_client *i2c)1150{1151struct adv7511_link_config link_config;1152struct adv7511 *adv7511;1153struct device *dev = &i2c->dev;1154unsigned int val;1155int ret;11561157if (!dev->of_node)1158return -EINVAL;11591160adv7511 = devm_drm_bridge_alloc(dev, struct adv7511, bridge,1161&adv7511_bridge_funcs);1162if (IS_ERR(adv7511))1163return PTR_ERR(adv7511);11641165adv7511->i2c_main = i2c;1166adv7511->powered = false;1167adv7511->status = connector_status_disconnected;1168adv7511->info = i2c_get_match_data(i2c);11691170memset(&link_config, 0, sizeof(link_config));11711172ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,1173&adv7511->next_bridge);1174if (ret && ret != -ENODEV)1175return ret;11761177if (adv7511->info->link_config)1178ret = adv7511_parse_dt(dev->of_node, &link_config);1179else1180ret = adv7533_parse_dt(dev->of_node, adv7511);1181if (ret)1182return ret;11831184ret = adv7511_init_regulators(adv7511);1185if (ret) {1186dev_err_probe(dev, ret, "failed to init regulators\n");1187goto err_of_node_put;1188}11891190/*1191* The power down GPIO is optional. If present, toggle it from active to1192* inactive to wake up the encoder.1193*/1194adv7511->gpio_pd = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_HIGH);1195if (IS_ERR(adv7511->gpio_pd)) {1196ret = PTR_ERR(adv7511->gpio_pd);1197goto uninit_regulators;1198}11991200if (adv7511->gpio_pd) {1201usleep_range(5000, 6000);1202gpiod_set_value_cansleep(adv7511->gpio_pd, 0);1203}12041205adv7511->regmap = devm_regmap_init_i2c(i2c, &adv7511_regmap_config);1206if (IS_ERR(adv7511->regmap)) {1207ret = PTR_ERR(adv7511->regmap);1208goto uninit_regulators;1209}12101211ret = regmap_read(adv7511->regmap, ADV7511_REG_CHIP_REVISION, &val);1212if (ret)1213goto uninit_regulators;1214dev_dbg(dev, "Rev. %d\n", val);12151216if (adv7511->info->type == ADV7511)1217ret = regmap_register_patch(adv7511->regmap,1218adv7511_fixed_registers,1219ARRAY_SIZE(adv7511_fixed_registers));1220else1221ret = adv7533_patch_registers(adv7511);1222if (ret)1223goto uninit_regulators;12241225adv7511_packet_disable(adv7511, 0xffff);12261227adv7511->i2c_edid = i2c_new_ancillary_device(i2c, "edid",1228ADV7511_EDID_I2C_ADDR_DEFAULT);1229if (IS_ERR(adv7511->i2c_edid)) {1230ret = PTR_ERR(adv7511->i2c_edid);1231goto uninit_regulators;1232}12331234regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,1235adv7511->i2c_edid->addr << 1);12361237adv7511->i2c_packet = i2c_new_ancillary_device(i2c, "packet",1238ADV7511_PACKET_I2C_ADDR_DEFAULT);1239if (IS_ERR(adv7511->i2c_packet)) {1240ret = PTR_ERR(adv7511->i2c_packet);1241goto err_i2c_unregister_edid;1242}12431244regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,1245adv7511->i2c_packet->addr << 1);12461247ret = adv7511_init_cec_regmap(adv7511);1248if (ret)1249goto err_i2c_unregister_packet;12501251INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);12521253adv7511_power_off(adv7511);12541255i2c_set_clientdata(i2c, adv7511);12561257if (adv7511->info->link_config)1258adv7511_set_link_config(adv7511, &link_config);12591260regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,1261ADV7511_CEC_CTRL_POWER_DOWN);12621263adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT |1264DRM_BRIDGE_OP_EDID |1265DRM_BRIDGE_OP_HDMI;1266if (adv7511->i2c_main->irq)1267adv7511->bridge.ops |= DRM_BRIDGE_OP_HPD;12681269adv7511->bridge.vendor = "Analog";1270adv7511->bridge.product = adv7511->info->name;12711272#ifdef CONFIG_DRM_I2C_ADV7511_AUDIO1273adv7511->bridge.ops |= DRM_BRIDGE_OP_HDMI_AUDIO;1274adv7511->bridge.hdmi_audio_dev = dev;1275adv7511->bridge.hdmi_audio_max_i2s_playback_channels = 2;1276adv7511->bridge.hdmi_audio_i2s_formats = (SNDRV_PCM_FMTBIT_S16_LE |1277SNDRV_PCM_FMTBIT_S20_3LE |1278SNDRV_PCM_FMTBIT_S24_3LE |1279SNDRV_PCM_FMTBIT_S24_LE |1280SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),1281adv7511->bridge.hdmi_audio_spdif_playback = 1;1282adv7511->bridge.hdmi_audio_dai_port = 2;1283#endif12841285#ifdef CONFIG_DRM_I2C_ADV7511_CEC1286adv7511->bridge.ops |= DRM_BRIDGE_OP_HDMI_CEC_ADAPTER;1287adv7511->bridge.hdmi_cec_dev = dev;1288adv7511->bridge.hdmi_cec_adapter_name = dev_name(dev);1289adv7511->bridge.hdmi_cec_available_las = ADV7511_MAX_ADDRS;1290#endif12911292adv7511->bridge.of_node = dev->of_node;1293adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA;12941295drm_bridge_add(&adv7511->bridge);12961297if (i2c->irq) {1298init_waitqueue_head(&adv7511->wq);12991300ret = devm_request_threaded_irq(dev, i2c->irq, NULL,1301adv7511_irq_handler,1302IRQF_ONESHOT | IRQF_SHARED,1303dev_name(dev),1304adv7511);1305if (ret)1306goto err_unregister_audio;1307}13081309if (adv7511->info->has_dsi) {1310ret = adv7533_attach_dsi(adv7511);1311if (ret)1312goto err_unregister_audio;1313}13141315return 0;13161317err_unregister_audio:1318drm_bridge_remove(&adv7511->bridge);1319i2c_unregister_device(adv7511->i2c_cec);1320clk_disable_unprepare(adv7511->cec_clk);1321err_i2c_unregister_packet:1322i2c_unregister_device(adv7511->i2c_packet);1323err_i2c_unregister_edid:1324i2c_unregister_device(adv7511->i2c_edid);1325uninit_regulators:1326adv7511_uninit_regulators(adv7511);1327err_of_node_put:1328of_node_put(adv7511->host_node);13291330return ret;1331}13321333static void adv7511_remove(struct i2c_client *i2c)1334{1335struct adv7511 *adv7511 = i2c_get_clientdata(i2c);13361337of_node_put(adv7511->host_node);13381339adv7511_uninit_regulators(adv7511);13401341drm_bridge_remove(&adv7511->bridge);13421343i2c_unregister_device(adv7511->i2c_cec);1344clk_disable_unprepare(adv7511->cec_clk);13451346i2c_unregister_device(adv7511->i2c_packet);1347i2c_unregister_device(adv7511->i2c_edid);1348}13491350static const struct adv7511_chip_info adv7511_chip_info = {1351.type = ADV7511,1352.name = "ADV7511",1353.max_mode_clock_khz = 165000,1354.supply_names = adv7511_supply_names,1355.num_supplies = ARRAY_SIZE(adv7511_supply_names),1356.link_config = true,1357};13581359static const struct adv7511_chip_info adv7533_chip_info = {1360.type = ADV7533,1361.name = "ADV7533",1362.max_mode_clock_khz = 80000,1363.max_lane_freq_khz = 800000,1364.supply_names = adv7533_supply_names,1365.num_supplies = ARRAY_SIZE(adv7533_supply_names),1366.reg_cec_offset = ADV7533_REG_CEC_OFFSET,1367.has_dsi = true,1368};13691370static const struct adv7511_chip_info adv7535_chip_info = {1371.type = ADV7535,1372.name = "ADV7535",1373.max_mode_clock_khz = 148500,1374.max_lane_freq_khz = 891000,1375.supply_names = adv7533_supply_names,1376.num_supplies = ARRAY_SIZE(adv7533_supply_names),1377.reg_cec_offset = ADV7533_REG_CEC_OFFSET,1378.has_dsi = true,1379.hpd_override_enable = true,1380};13811382static const struct i2c_device_id adv7511_i2c_ids[] = {1383{ "adv7511", (kernel_ulong_t)&adv7511_chip_info },1384{ "adv7511w", (kernel_ulong_t)&adv7511_chip_info },1385{ "adv7513", (kernel_ulong_t)&adv7511_chip_info },1386{ "adv7533", (kernel_ulong_t)&adv7533_chip_info },1387{ "adv7535", (kernel_ulong_t)&adv7535_chip_info },1388{ }1389};1390MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids);13911392static const struct of_device_id adv7511_of_ids[] = {1393{ .compatible = "adi,adv7511", .data = &adv7511_chip_info },1394{ .compatible = "adi,adv7511w", .data = &adv7511_chip_info },1395{ .compatible = "adi,adv7513", .data = &adv7511_chip_info },1396{ .compatible = "adi,adv7533", .data = &adv7533_chip_info },1397{ .compatible = "adi,adv7535", .data = &adv7535_chip_info },1398{ }1399};1400MODULE_DEVICE_TABLE(of, adv7511_of_ids);14011402static struct mipi_dsi_driver adv7533_dsi_driver = {1403.driver.name = "adv7533",1404};14051406static struct i2c_driver adv7511_driver = {1407.driver = {1408.name = "adv7511",1409.of_match_table = adv7511_of_ids,1410},1411.id_table = adv7511_i2c_ids,1412.probe = adv7511_probe,1413.remove = adv7511_remove,1414};14151416static int __init adv7511_init(void)1417{1418int ret;14191420if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {1421ret = mipi_dsi_driver_register(&adv7533_dsi_driver);1422if (ret)1423return ret;1424}14251426ret = i2c_add_driver(&adv7511_driver);1427if (ret) {1428if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))1429mipi_dsi_driver_unregister(&adv7533_dsi_driver);1430}14311432return ret;1433}1434module_init(adv7511_init);14351436static void __exit adv7511_exit(void)1437{1438i2c_del_driver(&adv7511_driver);14391440if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))1441mipi_dsi_driver_unregister(&adv7533_dsi_driver);1442}1443module_exit(adv7511_exit);14441445MODULE_AUTHOR("Lars-Peter Clausen <[email protected]>");1446MODULE_DESCRIPTION("ADV7511 HDMI transmitter driver");1447MODULE_LICENSE("GPL");144814491450