#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <sound/hdmi-codec.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#define EDID_BLOCK_SIZE …
#define EDID_NUM_BLOCKS …
#define FW_FILE …
struct lt9611uxc { … };
#define LT9611_PAGE_CONTROL …
static const struct regmap_range_cfg lt9611uxc_ranges[] = …;
static const struct regmap_config lt9611uxc_regmap_config = …;
struct lt9611uxc_mode { … };
static struct lt9611uxc_mode lt9611uxc_modes[] = …;
static struct lt9611uxc *bridge_to_lt9611uxc(struct drm_bridge *bridge)
{ … }
static struct lt9611uxc *connector_to_lt9611uxc(struct drm_connector *connector)
{ … }
static void lt9611uxc_lock(struct lt9611uxc *lt9611uxc)
{ … }
static void lt9611uxc_unlock(struct lt9611uxc *lt9611uxc)
{ … }
static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id)
{ … }
static void lt9611uxc_hpd_work(struct work_struct *work)
{ … }
static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc)
{ … }
static void lt9611uxc_assert_5v(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_regulator_init(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_regulator_enable(struct lt9611uxc *lt9611uxc)
{ … }
static struct lt9611uxc_mode *lt9611uxc_find_mode(const struct drm_display_mode *mode)
{ … }
static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc,
struct device_node *dsi_node)
{ … }
static int lt9611uxc_connector_get_modes(struct drm_connector *connector)
{ … }
static enum drm_connector_status lt9611uxc_connector_detect(struct drm_connector *connector,
bool force)
{ … }
static enum drm_mode_status lt9611uxc_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{ … }
static const struct drm_connector_helper_funcs lt9611uxc_bridge_connector_helper_funcs = …;
static const struct drm_connector_funcs lt9611uxc_bridge_connector_funcs = …;
static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{ … }
static enum drm_mode_status
lt9611uxc_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode)
{ … }
static void lt9611uxc_video_setup(struct lt9611uxc *lt9611uxc,
const struct drm_display_mode *mode)
{ … }
static void lt9611uxc_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adj_mode)
{ … }
static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *bridge)
{ … }
static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
{
struct lt9611uxc *lt9611uxc = data;
int ret;
if (len > EDID_BLOCK_SIZE)
return -EINVAL;
if (block >= EDID_NUM_BLOCKS)
return -EINVAL;
lt9611uxc_lock(lt9611uxc);
regmap_write(lt9611uxc->regmap, 0xb00b, 0x10);
regmap_write(lt9611uxc->regmap, 0xb00a, block * EDID_BLOCK_SIZE);
ret = regmap_noinc_read(lt9611uxc->regmap, 0xb0b0, buf, len);
if (ret)
dev_err(lt9611uxc->dev, "edid read failed: %d\n", ret);
lt9611uxc_unlock(lt9611uxc);
return 0;
};
static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *bridge,
struct drm_connector *connector)
{ … }
static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = …;
static int lt9611uxc_parse_dt(struct device *dev,
struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_gpio_init(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_read_device_rev(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_read_version(struct lt9611uxc *lt9611uxc)
{ … }
static int lt9611uxc_hdmi_hw_params(struct device *dev, void *data,
struct hdmi_codec_daifmt *fmt,
struct hdmi_codec_params *hparms)
{ … }
static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
{ … }
static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
struct device_node *endpoint)
{ … }
static const struct hdmi_codec_ops lt9611uxc_codec_ops = …;
static int lt9611uxc_audio_init(struct device *dev, struct lt9611uxc *lt9611uxc)
{ … }
static void lt9611uxc_audio_exit(struct lt9611uxc *lt9611uxc)
{ … }
#define LT9611UXC_FW_PAGE_SIZE …
static void lt9611uxc_firmware_write_page(struct lt9611uxc *lt9611uxc, u16 addr, const u8 *buf)
{ … }
static void lt9611uxc_firmware_read_page(struct lt9611uxc *lt9611uxc, u16 addr, char *buf)
{ … }
static char *lt9611uxc_firmware_read(struct lt9611uxc *lt9611uxc, size_t size)
{ … }
static int lt9611uxc_firmware_update(struct lt9611uxc *lt9611uxc)
{ … }
static ssize_t lt9611uxc_firmware_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
{ … }
static ssize_t lt9611uxc_firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR_RW(lt9611uxc_firmware);
static struct attribute *lt9611uxc_attrs[] = …;
static const struct attribute_group lt9611uxc_attr_group = …;
static const struct attribute_group *lt9611uxc_attr_groups[] = …;
static int lt9611uxc_probe(struct i2c_client *client)
{ … }
static void lt9611uxc_remove(struct i2c_client *client)
{ … }
static struct i2c_device_id lt9611uxc_id[] = …;
static const struct of_device_id lt9611uxc_match_table[] = …;
MODULE_DEVICE_TABLE(of, lt9611uxc_match_table);
static struct i2c_driver lt9611uxc_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_FIRMWARE(…);