/** * drm_i2c_encoder_init - Initialize an I2C slave encoder * @dev: DRM device. * @encoder: Encoder to be attached to the I2C device. You aren't * required to have called drm_encoder_init() before. * @adap: I2C adapter that will be used to communicate with * the device. * @info: Information that will be used to create the I2C device. * Required fields are @addr and @type. * * Create an I2C device on the specified bus (the module containing its * driver is transparently loaded) and attach it to the specified * &drm_encoder_slave. The @slave_funcs field will be initialized with * the hooks provided by the slave driver. * * If @info->platform_data is non-NULL it will be used as the initial * slave config. * * Returns 0 on success or a negative errno on failure, in particular, * -ENODEV is returned when no matching driver is found. */ int drm_i2c_encoder_init(struct drm_device *dev, struct drm_encoder_slave *encoder, struct i2c_adapter *adap, const struct i2c_board_info *info) { struct module *module = NULL; struct i2c_client *client; struct drm_i2c_encoder_driver *encoder_drv; int err = 0; request_module("%s%s", I2C_MODULE_PREFIX, info->type); client = i2c_new_device(adap, info); if (!client) { err = -ENOMEM; goto fail; } if (!client->driver) { err = -ENODEV; goto fail_unregister; } module = client->driver->driver.owner; if (!try_module_get(module)) { err = -ENODEV; goto fail_unregister; } encoder->bus_priv = client; encoder_drv = to_drm_i2c_encoder_driver(client->driver); err = encoder_drv->encoder_init(client, dev, encoder); if (err) goto fail_unregister; if (info->platform_data) encoder->slave_funcs->set_config(&encoder->base, info->platform_data); return 0; fail_unregister: i2c_unregister_device(client); module_put(module); fail: return err; }
int drm_i2c_encoder_init(struct drm_device *dev, struct drm_encoder_slave *encoder, struct i2c_adapter *adap, const struct i2c_board_info *info) { char modalias[sizeof(I2C_MODULE_PREFIX) + I2C_NAME_SIZE]; struct module *module = NULL; struct i2c_client *client; struct drm_i2c_encoder_driver *encoder_drv; int err = 0; snprintf(modalias, sizeof(modalias), "%s%s", I2C_MODULE_PREFIX, info->type); request_module(modalias); client = i2c_new_device(adap, info); if (!client) { err = -ENOMEM; goto fail; } if (!client->driver) { err = -ENODEV; goto fail_unregister; } module = client->driver->driver.owner; if (!try_module_get(module)) { err = -ENODEV; goto fail_unregister; } encoder->bus_priv = client; encoder_drv = to_drm_i2c_encoder_driver(client->driver); err = encoder_drv->encoder_init(client, dev, encoder); if (err) goto fail_unregister; return 0; fail_unregister: i2c_unregister_device(client); module_put(module); fail: return err; }
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, struct device_node *np) { struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc); struct drm_i2c_encoder_driver *driver; struct i2c_client *i2c_slave; struct rcar_du_hdmienc *hdmienc; int ret; hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL); if (hdmienc == NULL) return -ENOMEM; /* Locate the slave I2C device and driver. */ i2c_slave = of_find_i2c_device_by_node(np); if (!i2c_slave || !i2c_get_clientdata(i2c_slave)) return -EPROBE_DEFER; hdmienc->dev = &i2c_slave->dev; if (hdmienc->dev->driver == NULL) { ret = -EPROBE_DEFER; goto error; } /* Initialize the slave encoder. */ driver = to_drm_i2c_encoder_driver(to_i2c_driver(hdmienc->dev->driver)); ret = driver->encoder_init(i2c_slave, rcdu->ddev, &renc->slave); if (ret < 0) goto error; ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, DRM_MODE_ENCODER_TMDS); if (ret < 0) goto error; drm_encoder_helper_add(encoder, &encoder_helper_funcs); renc->hdmi = hdmienc; hdmienc->renc = renc; return 0; error: put_device(hdmienc->dev); return ret; }
/* create encoder */ struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm, struct device_node *node) { struct xilinx_drm_encoder *encoder; struct i2c_client *i2c_slv; struct i2c_driver *i2c_driver; struct drm_i2c_encoder_driver *drm_i2c_driver; struct device_driver *device_driver; struct platform_device *platform_slv; struct platform_driver *platform_driver; struct drm_platform_encoder_driver *drm_platform_driver; int ret = 0; encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL); if (!encoder) return ERR_PTR(-ENOMEM); encoder->dpms = DRM_MODE_DPMS_OFF; /* FIXME: Use DT to figure out crtcs / clones */ encoder->slave.base.possible_crtcs = 1; encoder->slave.base.possible_clones = ~0; ret = drm_encoder_init(drm, &encoder->slave.base, &xilinx_drm_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) { DRM_ERROR("failed to initialize drm encoder\n"); return ERR_PTR(ret); } drm_encoder_helper_add(&encoder->slave.base, &xilinx_drm_encoder_helper_funcs); /* initialize slave encoder */ i2c_slv = of_find_i2c_device_by_node(node); if (i2c_slv && i2c_slv->dev.driver) { i2c_driver = to_i2c_driver(i2c_slv->dev.driver); drm_i2c_driver = to_drm_i2c_encoder_driver(i2c_driver); if (!drm_i2c_driver) { DRM_ERROR("failed to initialize i2c slave\n"); ret = -EPROBE_DEFER; goto err_out; } encoder->dev = &i2c_slv->dev; ret = drm_i2c_driver->encoder_init(i2c_slv, drm, &encoder->slave); } else { platform_slv = of_find_device_by_node(node); if (!platform_slv) { DRM_DEBUG_KMS("failed to get an encoder slv\n"); return ERR_PTR(-EPROBE_DEFER); } device_driver = platform_slv->dev.driver; if (!device_driver) { DRM_DEBUG_KMS("failed to get device driver\n"); return ERR_PTR(-EPROBE_DEFER); } platform_driver = to_platform_driver(device_driver); drm_platform_driver = to_drm_platform_encoder_driver(platform_driver); if (!drm_platform_driver) { DRM_ERROR("failed to initialize platform slave\n"); ret = -EPROBE_DEFER; goto err_out; } encoder->dev = &platform_slv->dev; ret = drm_platform_driver->encoder_init(platform_slv, drm, &encoder->slave); } if (ret) { DRM_ERROR("failed to initialize encoder slave\n"); goto err_out; } if (!encoder->slave.slave_funcs) { DRM_ERROR("there's no encoder slave function\n"); ret = -ENODEV; goto err_out; } return &encoder->slave.base; err_out: return ERR_PTR(ret); }
/* create encoder */ struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm) { struct xilinx_drm_encoder *encoder; struct device_node *sub_node; struct i2c_driver *i2c_driver; struct drm_i2c_encoder_driver *drm_i2c_driver; struct device_driver *device_driver; struct platform_driver *platform_driver; struct drm_platform_encoder_driver *drm_platform_driver; int ret = 0; encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL); if (!encoder) return ERR_PTR(-ENOMEM); encoder->dpms = DRM_MODE_DPMS_OFF; /* initialize encoder */ encoder->slave.base.possible_crtcs = 1; ret = drm_encoder_init(drm, &encoder->slave.base, &xilinx_drm_encoder_funcs, DRM_MODE_ENCODER_TMDS); if (ret) { DRM_ERROR("failed to initialize drm encoder\n"); return ERR_PTR(ret); } drm_encoder_helper_add(&encoder->slave.base, &xilinx_drm_encoder_helper_funcs); /* get slave encoder */ sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,encoder-slave", 0); if (!sub_node) { DRM_ERROR("failed to get an encoder slave node\n"); return ERR_PTR(-ENODEV); } /* initialize slave encoder */ encoder->i2c_slv = of_find_i2c_device_by_node(sub_node); if (encoder->i2c_slv) { i2c_driver = to_i2c_driver(encoder->i2c_slv->dev.driver); drm_i2c_driver = to_drm_i2c_encoder_driver(i2c_driver); if (!drm_i2c_driver) { DRM_ERROR("failed to initialize i2c slave\n"); ret = -EPROBE_DEFER; goto err_out; } ret = drm_i2c_driver->encoder_init(encoder->i2c_slv, drm, &encoder->slave); } else { encoder->platform_slv = of_find_device_by_node(sub_node); if (!encoder->platform_slv) { DRM_DEBUG_KMS("failed to get an encoder slv\n"); return ERR_PTR(-EPROBE_DEFER); } device_driver = encoder->platform_slv->dev.driver; if (!device_driver) { DRM_DEBUG_KMS("failed to get device driver\n"); return ERR_PTR(-EPROBE_DEFER); } platform_driver = to_platform_driver(device_driver); drm_platform_driver = to_drm_platform_encoder_driver(platform_driver); if (!drm_platform_driver) { DRM_ERROR("failed to initialize platform slave\n"); ret = -EPROBE_DEFER; goto err_out; } ret = drm_platform_driver->encoder_init(encoder->platform_slv, drm, &encoder->slave); } of_node_put(sub_node); if (ret) { DRM_ERROR("failed to initialize encoder slave\n"); goto err_out; } if (!encoder->slave.slave_funcs) { DRM_ERROR("there's no encoder slave function\n"); ret = -ENODEV; goto err_out; } return &encoder->slave.base; err_out: return ERR_PTR(ret); }