/* If this is the alerting device, notify its driver */ static int smbus_do_alert(struct device *dev, void *addrp) { struct i2c_client *client = i2c_verify_client(dev); struct alert_data *data = addrp; struct i2c_driver *driver; if (!client || client->addr != data->addr) return 0; if (client->flags & I2C_CLIENT_TEN) return 0; /* * Drivers should either disable alerts, or provide at least * a minimal handler. Lock so the driver won't change. */ device_lock(dev); if (client->dev.driver) { driver = to_i2c_driver(client->dev.driver); if (driver->alert) driver->alert(client, data->flag); else dev_warn(&client->dev, "no driver alert()!\n"); } else dev_dbg(&client->dev, "alert with no driver\n"); device_unlock(dev); /* Stop iterating after we find the device */ return -EBUSY; }
static bool probe_monitoring_device(struct nouveau_i2c_port *i2c, struct i2c_board_info *info, void *data) { struct nouveau_therm_priv *priv = data; struct nvbios_therm_sensor *sensor = &priv->bios_sensor; struct i2c_client *client; request_module("%s%s", I2C_MODULE_PREFIX, info->type); client = i2c_new_device(&i2c->adapter, info); if (!client) return false; if (!client->dev.driver || to_i2c_driver(client->dev.driver)->detect(client, info)) { i2c_unregister_device(client); return false; } nv_info(priv, "Found an %s at address 0x%x (controlled by lm_sensors, " "temp offset %+i C)\n", info->type, info->addr, sensor->offset_constant); priv->ic = client; return true; }
static const struct i2c_device_id *i2c_get_device_id( const struct i2c_client *idev) { const struct i2c_driver *idrv = to_i2c_driver(idev->dev.driver); return i2c_match_id(idrv->id_table, idev); }
/** * 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->dev.driver) { err = -ENODEV; goto fail_unregister; } module = client->dev.driver->owner; if (!try_module_get(module)) { err = -ENODEV; goto fail_unregister; } encoder->bus_priv = client; encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.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 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; }
static int mc13xxx_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { const struct of_device_id *of_id; struct i2c_driver *idrv = to_i2c_driver(client->dev.driver); struct mc13xxx *mc13xxx; struct mc13xxx_platform_data *pdata = dev_get_platdata(&client->dev); int ret; of_id = of_match_device(mc13xxx_dt_ids, &client->dev); if (of_id) idrv->id_table = (const struct i2c_device_id*) of_id->data; mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); if (!mc13xxx) return -ENOMEM; dev_set_drvdata(&client->dev, mc13xxx); mc13xxx->dev = &client->dev; mutex_init(&mc13xxx->lock); mc13xxx->regmap = regmap_init_i2c(client, &mc13xxx_regmap_i2c_config); if (IS_ERR(mc13xxx->regmap)) { ret = PTR_ERR(mc13xxx->regmap); dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", ret); dev_set_drvdata(&client->dev, NULL); kfree(mc13xxx); return ret; } ret = mc13xxx_common_init(mc13xxx, pdata, client->irq); if (ret == 0 && (id->driver_data != mc13xxx->ictype)) dev_warn(mc13xxx->dev, "device id doesn't match auto detection!\n"); 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); }