Загрузка данных
static int lt9611_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
if(lt9611->next_bridge) {
return drm_bridge_attach(bridge->encoder, lt9611->next_bridge, bridge, flags);
}
return 0;
}
static const struct drm_bridge_funcs lt9611_bridge_funcs = {
.attach = lt9611_bridge_attach,
.mode_valid = lt9611_bridge_mode_valid,
.detect = lt9611_bridge_detect,
.edid_read = lt9611_bridge_edid_read,
.hpd_enable = lt9611_bridge_hpd_enable,
.atomic_pre_enable = lt9611_bridge_atomic_pre_enable,
.atomic_enable = lt9611_bridge_atomic_enable,
.atomic_disable = lt9611_bridge_atomic_disable,
.atomic_post_disable = lt9611_bridge_atomic_post_disable,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts,
};
static int lt9611_parse_dt(struct device *dev, struct lt9611 *lt9611)
{
int ret = 0;
lt9611->dsi0_node = of_graph_get_remote_node(dev->of_node, 0, -1);
if (!lt9611->dsi0_node) {
dev_err(lt9611->dev, "failed to get remote node for primary dsi\n");
return -ENODEV;
}
lt9611->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
ret = drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, <9611->next_bridge);
if(ret == -ENODEV) {
lt9611->next_bridge = NULL;
return 0;
}
return ret;
}
static int lt9611_probe(struct i2c_client *client)
{
struct lt9611 *lt9611;
struct device *dev = &client->dev;
int ret;
bool is_i2s = true;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(dev, "device doesn't support I2C\n");
return -ENODEV;
}
lt9611 = devm_kzalloc(dev, sizeof(*lt9611), GFP_KERNEL);
if (!lt9611)
return -ENOMEM;
lt9611->dev = dev;
lt9611->client = client;
lt9611->sleep = false;
lt9611->regmap = devm_regmap_init_i2c(client, <9611_regmap_config);
if (IS_ERR(lt9611->regmap)) {
dev_err(lt9611->dev, "regmap i2c init failed\n");
return PTR_ERR(lt9611->regmap);
}
ret = lt9611_parse_dt(dev, lt9611);
if (ret) {
dev_err(dev, "failed to parse device tree\n");
return ret;
}
if (of_property_read_bool(dev->of_node, "fsl,audio-spdif")) {
is_i2s = false;
}
ret = lt9611_gpio_init(lt9611);
if (ret < 0)
goto err_of_put;
ret = lt9611_regulator_init(lt9611);
if (ret < 0)
goto err_of_put;
lt9611_assert_5v(lt9611);
ret = lt9611_regulator_enable(lt9611);
if (ret)
goto err_of_put;
lt9611_reset(lt9611);
ret = lt9611_read_device_rev(lt9611);
if (ret) {
dev_err(dev, "failed to read chip rev\n");
goto err_disable_regulators;
}
ret = devm_request_threaded_irq(dev, client->irq, NULL,lt9611_irq_thread_handler,IRQF_ONESHOT, "lt9611", lt9611);
if (ret) {
dev_err(dev, "failed to request irq\n");
goto err_disable_regulators;
}
i2c_set_clientdata(client, lt9611);
lt9611->bridge.funcs = <9611_bridge_funcs;
lt9611->bridge.of_node = client->dev.of_node;
lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES;
lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
drm_bridge_add(<9611->bridge);
#ifdef MY_CODE
/* Attach primary DSI */
lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node);
if (IS_ERR(lt9611->dsi0)) {
ret = PTR_ERR(lt9611->dsi0);
goto err_remove_bridge;
}
#endif
lt9611_enable_hpd_interrupts(lt9611);
//CEC
mutex_init(<9611->cec_ioctl_mutex);
init_completion(<9611->rx_ok);
pdata_global = lt9611;
ret = cec_sysfs_init();
if (ret) {
printk("Error cec sysfs init");
}
else
{
ret = register_chrdev(0, CEC_DEV_NAME, &hdmitx_cec_fops);
if (ret < 0)
printk("%s alloc chrdev CEC failed\n",__FUNCTION__);
else
{
lt9611->cec_dev_no = ret;
cec_sysfs_dev_new(lt9611);
}
}
ret = lt9611_audio_init(dev, lt9611, is_i2s);
if (ret)
goto err_remove_bridge;
return 0;
err_remove_bridge:
drm_bridge_remove(<9611->bridge);
err_disable_regulators:
regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
err_of_put:
of_node_put(lt9611->dsi1_node);
of_node_put(lt9611->dsi0_node);
return ret;
}
static struct i2c_driver lt9611_driver = {
.driver = {
.name = "lt9611",
.of_match_table = lt9611_match_table,
},
.probe = lt9611_probe,
.remove = lt9611_remove,
.id_table = lt9611_id,
};
module_i2c_driver(lt9611_driver);