On Thu, 30 Jan 2014 14:20:56 +0200 Jyri Sarha <jsarha@xxxxxx> wrote: > I am having trouble getting the tda998x-codec working on BBB. The > problem is I do not have a DT node for the tda998x driver. Instead I > have tilcdc-slave node that provides pdata for the tda-driver. > > I am thinking of solving the problem by adding a reference to the > i2c-adapter hosting tda998x as an optional DT property to the codec > node. I could then dig the driver instance from the i2c adapter's > children. Any better ideas? I better think about a 'normal' DT definition: - in the DT, define the tda998x in a i2c subnode: &i2c0 { tda998x: hdmi-encoder { compatible = "nxp,tda998x"; reg = <0x70>; /* the video ports are OK by default */ /* define the interrupt if you want to use it */ }; }; - in tilcdc_slave.c, in the function slave_encoder_create(), instead of using drm_i2c_encoder_init(), do quite the same, but without calling request_module() nor i2c_new_device(). This can be done as follows (the code is not compiled): --------------------8<--------------------- static struct drm_encoder *slave_encoder_create(struct drm_device *dev, struct slave_module *mod) { struct slave_encoder *slave_encoder; struct drm_encoder *encoder; int ret; /* ------ added ------ */ struct device_node *np; static const struct of_device_id tda_dt[] = { { .compatible = "nxp,tda998x" }, { }, }; /* ------ end added ------ */ ... no change ... drm_encoder_helper_add(encoder, &slave_encoder_helper_funcs); /* ------ added ------ */ /* search the tda998x device */ np = of_find_matching_node_and_match(NULL, tda_dt, NULL); if (np && of_device_is_available(np)) { struct i2c_client *i2c_client; struct drm_i2c_encoder_driver *encoder_drv; struct module *module; /* the tda998x is in the DT */ i2c_client = of_find_i2c_device_by_node(np); of_node_put(np); if (!i2c_client) { dev_err(dev->dev, "no tda998x i2c client\n"); goto fail; } to_encoder_slave(encoder)->bus_priv = i2c_client; encoder_drv = to_drm_i2c_encoder_driver( to_i2c_driver(i2c_client->dev.driver)); /* lock the tda998x module in memory */ module = to_i2c_driver(i2c_client->dev.driver)->driver.owner; if (!module || !try_module_get(module)) { dev_err(dev->dev, "cannot get module %s\n", module->name); goto fail; } ret = encoder_drv->encoder_init(i2c_client, dev, encoder_slave); if (ret < 0) { dev_err(dev->dev, "slave encoder init failed\n"); module_put(module); goto fail; } /* set_config is useless */ return encoder; } /* ------ end added ------ */ ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), mod->i2c, &info); if (ret) goto fail; return encoder; fail: slave_encoder_destroy(encoder); return NULL; } --------------------8<--------------------- When the tda998x is in the DT, the i2c_client is already created. It must not be freed, and so, the function drm_i2c_encoder_destroy() must not be called. But, the module must be explicitly unlocked in slave_encoder_destroy(), and then, there must be some flag in the structures for this job to be done... -- Ken ar c'hentañ | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/ _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel