static int s35392a_attach(struct i2c_adapter* adapter, int address, int kind) { int ret; struct rtc_device *rtc = NULL; if (i2c_adapter_id(adapter) != 1) /* rtc is on i2c-1 */ { return -ENODEV; } gClient.addr = address; gClient.adapter = adapter; gClient.driver = &s35392a_driver; gClient.flags = 0; strlcpy(gClient.name, S35392A_DEV_NAME, I2C_NAME_SIZE); MYTRACE(("%s\n", __func__)); MYTRACE(("Adapter : %d\n", i2c_adapter_id(adapter))); MYTRACE(("ADDR : %x\n", gClient.addr)); ret = i2c_attach_client(&gClient); if (ret < 0) { MYTRACE(("i2c attach failed : %s\n", __func__)); } rtc = rtc_device_register(gClient.name, &gClient.dev, &s35392a_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { MYTRACE(("RTC driver regist failed!\n")); } return ret; }
static int tda18271_get_id(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; char *name; mutex_lock(&priv->lock); tda18271_read_regs(fe); mutex_unlock(&priv->lock); switch (regs[R_ID] & 0x7f) { case 3: name = "TDA18271HD/C1"; priv->id = TDA18271HDC1; break; case 4: name = "TDA18271HD/C2"; priv->id = TDA18271HDC2; break; default: tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n", regs[R_ID], i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr); return -EINVAL; } tda_info("%s detected @ %d-%04x\n", name, i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr); return 0; }
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, void *mux_dev, u32 force_nr, u32 chan_id, int (*select) (struct i2c_adapter *, void *, u32), int (*deselect) (struct i2c_adapter *, void *, u32)) { struct i2c_mux_priv *priv; int ret; priv = kzalloc(sizeof(struct i2c_mux_priv), GFP_KERNEL); if (!priv) return NULL; priv->parent = parent; priv->mux_dev = mux_dev; priv->chan_id = chan_id; priv->select = select; priv->deselect = deselect; if (parent->algo->master_xfer) priv->algo.master_xfer = i2c_mux_master_xfer; if (parent->algo->smbus_xfer) priv->algo.smbus_xfer = i2c_mux_smbus_xfer; priv->algo.functionality = i2c_mux_functionality; snprintf(priv->adap.name, sizeof(priv->adap.name), "i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id); priv->adap.owner = THIS_MODULE; priv->adap.algo = &priv->algo; priv->adap.algo_data = priv; priv->adap.dev.parent = &parent->dev; if (force_nr) { priv->adap.nr = force_nr; ret = i2c_add_numbered_adapter(&priv->adap); } else { ret = i2c_add_adapter(&priv->adap); } if (ret < 0) { dev_err(&parent->dev, "failed to add mux-adapter (error=%d)\n", ret); kfree(priv); return NULL; } dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", i2c_adapter_id(&priv->adap)); return &priv->adap; }
static int i2c_mux_reg_probe_dt(struct regmux *mux, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *adapter_np, *child; struct i2c_adapter *adapter; struct resource res; unsigned *values; int i = 0; if (!np) return -ENODEV; adapter_np = of_parse_phandle(np, "i2c-parent", 0); if (!adapter_np) { dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); return -ENODEV; } adapter = of_find_i2c_adapter_by_node(adapter_np); of_node_put(adapter_np); if (!adapter) return -EPROBE_DEFER; mux->data.parent = i2c_adapter_id(adapter); put_device(&adapter->dev); mux->data.n_values = of_get_child_count(np); if (of_find_property(np, "little-endian", NULL)) { mux->data.little_endian = true; } else if (of_find_property(np, "big-endian", NULL)) { mux->data.little_endian = false; } else { #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : \ defined(__LITTLE_ENDIAN) mux->data.little_endian = true; #elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : \ defined(__BIG_ENDIAN) mux->data.little_endian = false; #else #error Endianness not defined? #endif } if (of_find_property(np, "write-only", NULL)) mux->data.write_only = true; else mux->data.write_only = false; values = devm_kzalloc(&pdev->dev, sizeof(*mux->data.values) * mux->data.n_values, GFP_KERNEL); if (!values) { dev_err(&pdev->dev, "Cannot allocate values array"); return -ENOMEM; } for_each_child_of_node(np, child) { of_property_read_u32(child, "reg", values + i); i++; }
int i2c_tsp_sensor_read(u16 reg, u8 *read_val, unsigned int len ) { int id; int err, i; struct i2c_msg msg[1]; unsigned char data[2]; if( (g_client == NULL) || (!g_client->adapter) ) { return -ENODEV; } msg->addr = g_client->addr; msg->flags = I2C_M_WR; msg->len = 2; msg->buf = data; data[0] = reg & 0x00ff; data[1] = reg >> 8; err = i2c_transfer(g_client->adapter, msg, 1); #if 1//for debug if(g_i2c_debugging_enable == 1) { printk(KERN_DEBUG "[TSP][I2C] read addr[0] = 0x%x, addr[1] = 0x%x\n", data[0], data[1]); } #endif if (err >= 0) { msg->flags = I2C_M_RD; msg->len = len; msg->buf = read_val; err = i2c_transfer(g_client->adapter, msg, 1); #if 1//for debug if(g_i2c_debugging_enable == 1) { printk(KERN_DEBUG "[TSP][I2C] read data = "); for(i=0 ; i<len ; i++) { printk(KERN_DEBUG "%d(0x%x), ", msg->buf[i], msg->buf[i]); } printk(KERN_DEBUG "// len = %d, rtn=%d\n",msg->len, err); } #endif } if (err >= 0) { return 0; } id = i2c_adapter_id(g_client->adapter); // printk("[TSP] %s() - end\n", __FUNCTION__); return err; }
static int snd_ak4641_i2c_attach(struct snd_ak4641 *ak) { int ret = 0; if ((ret = snd_ak4641_i2c_probe(ak)) < 0) return ret; snprintf(ak->i2c_client.name, sizeof(ak->i2c_client.name), "ak4641-i2c at %d-%04x", i2c_adapter_id(ak->i2c_client.adapter), ak->i2c_client.addr); return i2c_attach_client(&ak->i2c_client); }
static int lis3lv02d_attach(struct i2c_adapter *adap) { int adap_id = i2c_adapter_id(adap); if (busnum == -1) return i2c_probe(adap, &addr_data, &lis3lv02d_do_probe); if (adap_id == busnum) return i2c_probe(adap, &addr_data, &lis3lv02d_do_probe); }
static int attach_adapter(struct i2c_adapter *adapter) { int retval = 0; if (i2c_adapter_id(adapter) == 1) { retval = i2c_probe(adapter, &addr_data, detect); } return retval; }
static int s35392a_probe(struct i2c_adapter* adapter) { int ret; MYTRACE(("ADAPTER id : %d\n", i2c_adapter_id(adapter))); ret = i2c_probe(adapter, &addr_data, &s35392a_attach); MYTRACE(("%s : %d\n", __func__, ret)); return ret; }
/** * gsensor_detect - Device detection callback for automatic device creation * return value: * = 0; success; * < 0; err */ static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; if(twi_id == adapter->nr){ pr_info("%s: Detected chip %s at adapter %d, address 0x%02x\n", __func__, SENSOR_NAME, i2c_adapter_id(adapter), client->addr); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; }else{ return -ENODEV; } }
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, const struct v4l2_subdev_ops *ops) { v4l2_subdev_init(sd, ops); sd->flags |= V4L2_SUBDEV_FL_IS_I2C; /* the owner is the same as the i2c_client's driver owner */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) sd->owner = client->driver->driver.owner; #else sd->owner = client->dev.driver->owner; #endif /* i2c_client and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); /* initialize name */ snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) client->driver->driver.name, i2c_adapter_id(client->adapter), #else client->dev.driver->name, i2c_adapter_id(client->adapter), #endif client->addr); }
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, const struct v4l2_subdev_ops *ops) { v4l2_subdev_init(sd, ops); sd->flags |= V4L2_SUBDEV_FL_IS_I2C; sd->owner = client->driver->driver.owner; v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", client->driver->driver.name, i2c_adapter_id(client->adapter), client->addr); }
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, const struct v4l2_subdev_ops *ops) { v4l2_subdev_init(sd, ops); sd->flags |= V4L2_SUBDEV_FL_IS_I2C; /* the owner is the same as the i2c_client's driver owner */ sd->owner = client->driver->driver.owner; /* i2c_client and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); /* initialize name */ snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", client->driver->driver.name, i2c_adapter_id(client->adapter), client->addr); }
/* This returns a nice name for a new directory; for example lm78-isa-0310 (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for a LM75 chip on the third i2c bus at address 0x4e). name is allocated first. */ int i2c_create_name(char **name, const char *prefix, struct i2c_adapter *adapter, int addr) { char name_buffer[50]; int id; if (i2c_is_isa_adapter(adapter)) sprintf(name_buffer, "%s-isa-%04x", prefix, addr); else { if ((id = i2c_adapter_id(adapter)) < 0) return -ENOENT; sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr); } *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL); strcpy(*name, name_buffer); return 0; }
static int tda8295_probe(struct tuner_i2c_props *i2c_props) { #define TDA8295_ID 0x8a unsigned char tda8295_id[] = { 0x2f, 0x00 }; /* detect tda8295 */ tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); if (tda8295_id[1] == TDA8295_ID) { if (debug) printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", __func__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); return 0; } return -ENODEV; }
static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *adapter_np, *child; struct i2c_adapter *adapter; unsigned *values, *gpios; int i = 0, ret; if (!np) return -ENODEV; adapter_np = of_parse_phandle(np, "i2c-parent", 0); if (!adapter_np) { dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); return -ENODEV; } adapter = of_find_i2c_adapter_by_node(adapter_np); if (!adapter) { dev_err(&pdev->dev, "Cannot find parent bus\n"); return -EPROBE_DEFER; } mux->data.parent = i2c_adapter_id(adapter); put_device(&adapter->dev); mux->data.n_values = of_get_child_count(np); values = devm_kzalloc(&pdev->dev, sizeof(*mux->data.values) * mux->data.n_values, GFP_KERNEL); if (!values) { dev_err(&pdev->dev, "Cannot allocate values array"); return -ENOMEM; } for_each_child_of_node(np, child) { of_property_read_u32(child, "reg", values + i); i++; }
int i2c_tsp_sensor_read(u8 reg, u8 *val, unsigned int len ) { int id; int err; struct i2c_msg msg[1]; unsigned char data[1]; if( (g_client == NULL) || (!g_client->adapter) ) { return -ENODEV; } msg->addr = g_client->addr; msg->flags = I2C_M_WR; msg->len = 1; msg->buf = data; *data = reg; err = i2c_transfer(g_client->adapter, msg, 1); if (err >= 0) { msg->flags = I2C_M_RD; msg->len = len; msg->buf = val; err = i2c_transfer(g_client->adapter, msg, 1); } if (err >= 0) { return 0; } id = i2c_adapter_id(g_client->adapter); return err; }
int i2cdev_attach_adapter(struct i2c_adapter *adap) { int i; char name[8]; if ((i = i2c_adapter_id(adap)) < 0) { printk(KERN_DEBUG "i2c-dev.o: Unknown adapter ?!?\n"); return -ENODEV; } if (i >= I2CDEV_ADAPS_MAX) { printk(KERN_DEBUG "i2c-dev.o: Adapter number too large?!? (%d)\n",i); return -ENODEV; } sprintf (name, "%d", i); if (! i2cdev_adaps[i]) { i2cdev_adaps[i] = adap; #ifdef CONFIG_DEVFS_FS devfs_i2c[i] = devfs_register (devfs_handle, name, DEVFS_FL_DEFAULT, I2C_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR, &i2cdev_fops, NULL); #endif printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); } else { /* This is actually a detach_adapter call! */ #ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_i2c[i]); #endif i2cdev_adaps[i] = NULL; #ifdef DEBUG printk(KERN_DEBUG "i2c-dev.o: Adapter unregistered: %s\n",adap->name); #endif } return 0; }
int inv_mpu_register_slave(struct module *slave_module, struct i2c_client *slave_client, struct ext_slave_platform_data *slave_pdata, struct ext_slave_descr *(*get_slave_descr)(void)) { struct mpu_private_data *mpu = mpu_private_data; struct mldl_cfg *mldl_cfg; struct ext_slave_descr *slave_descr; struct ext_slave_platform_data **pdata_slave; char *irq_name = NULL; int result = 0; if (!slave_client || !slave_pdata || !get_slave_descr) return -EINVAL; if (!mpu) { dev_err(&slave_client->adapter->dev, "%s: Null mpu_private_data\n", __func__); return -EINVAL; } mldl_cfg = &mpu->mldl_cfg; pdata_slave = mldl_cfg->pdata_slave; slave_descr = get_slave_descr(); if (!slave_descr) { dev_err(&slave_client->adapter->dev, "%s: Null ext_slave_descr\n", __func__); return -EINVAL; } mutex_lock(&mpu->mutex); if (mpu->pid) { mutex_unlock(&mpu->mutex); return -EBUSY; } if (pdata_slave[slave_descr->type]) { result = -EBUSY; goto out_unlock_mutex; } slave_pdata->address = slave_client->addr; slave_pdata->irq = slave_client->irq; slave_pdata->adapt_num = i2c_adapter_id(slave_client->adapter); dev_info(&slave_client->adapter->dev, "%s: +%s Type %d: Addr: %2x IRQ: %2d, Adapt: %2d\n", __func__, slave_descr->name, slave_descr->type, slave_pdata->address, slave_pdata->irq, slave_pdata->adapt_num); switch (slave_descr->type) { case EXT_SLAVE_TYPE_ACCEL: irq_name = "accelirq"; break; case EXT_SLAVE_TYPE_COMPASS: irq_name = "compassirq"; break; case EXT_SLAVE_TYPE_PRESSURE: irq_name = "pressureirq"; break; default: irq_name = "none"; }; if (slave_descr->init) { result = slave_descr->init(slave_client->adapter, slave_descr, slave_pdata); if (result) { dev_err(&slave_client->adapter->dev, "%s init failed %d\n", slave_descr->name, result); goto out_unlock_mutex; } } pdata_slave[slave_descr->type] = slave_pdata; mpu->slave_modules[slave_descr->type] = slave_module; mldl_cfg->slave[slave_descr->type] = slave_descr; goto out_unlock_mutex; out_unlock_mutex: mutex_unlock(&mpu->mutex); if (!result && irq_name && (slave_pdata->irq > 0)) { int warn_result; dev_info(&slave_client->adapter->dev, "Installing %s irq using %d\n", irq_name, slave_pdata->irq); warn_result = slaveirq_init(slave_client->adapter, slave_pdata, irq_name); if (result) dev_WARN(&slave_client->adapter->dev, "%s irq assigned error: %d\n", slave_descr->name, warn_result); } else { dev_info(&slave_client->adapter->dev, "%s irq not assigned: %d %d %d\n", slave_descr->name, result, (int)irq_name, slave_pdata->irq); } return result; }
/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ int i2c_detect(struct i2c_adapter *adapter, struct i2c_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)) { int addr, i, found, j, err; struct i2c_force_data *this_force; int is_isa = i2c_is_isa_adapter(adapter); int adapter_id = is_isa ? ANY_I2C_ISA_BUS : i2c_adapter_id(adapter); unsigned short *normal_i2c; unsigned int *normal_isa; unsigned short *probe; unsigned short *ignore; /* Forget it if we can't probe using SMBUS_QUICK */ if ((!is_isa) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) return -1; /* Use default "empty" list if the adapter doesn't specify any */ normal_i2c = probe = ignore = empty; normal_isa = empty_isa; if (address_data->normal_i2c) normal_i2c = address_data->normal_i2c; if (address_data->normal_isa) normal_isa = address_data->normal_isa; if (address_data->probe) probe = address_data->probe; if (address_data->ignore) ignore = address_data->ignore; for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { if (!is_isa && i2c_check_addr(adapter, addr)) continue; /* If it is in one of the force entries, we don't do any detection at all */ found = 0; for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { for (j = 0; !found && (this_force->force[j] != I2C_CLIENT_END); j += 2) { if ( ((adapter_id == this_force->force[j]) || ((this_force->force[j] == ANY_I2C_BUS) && !is_isa)) && (addr == this_force->force[j + 1]) ) { dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n", adapter_id, addr); if ((err = found_proc(adapter, addr, this_force->kind))) return err; found = 1; } } } if (found) continue; /* If this address is in one of the ignores, we can forget about it right now */ for (i = 0; !found && (ignore[i] != I2C_CLIENT_END); i += 2) { if ( ((adapter_id == ignore[i]) || ((ignore[i] == ANY_I2C_BUS) && !is_isa)) && (addr == ignore[i + 1])) { dev_dbg(&adapter->dev, "found ignore parameter for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } if (found) continue; /* Now, we will do a detection, but only if it is in the normal or probe entries */ if (is_isa) { for (i = 0; !found && (normal_isa[i] != I2C_CLIENT_ISA_END); i += 1) { if (addr == normal_isa[i]) { dev_dbg(&adapter->dev, "found normal isa entry for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } } else { for (i = 0; !found && (normal_i2c[i] != I2C_CLIENT_END); i += 1) { if (addr == normal_i2c[i]) { found = 1; dev_dbg(&adapter->dev, "found normal i2c entry for adapter %d, addr %02x\n", adapter_id, addr); } } } for (i = 0; !found && (probe[i] != I2C_CLIENT_END); i += 2) { if (((adapter_id == probe[i]) || ((probe[i] == ANY_I2C_BUS) && !is_isa)) && (addr == probe[i + 1])) { dev_dbg(&adapter->dev, "found probe parameter for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } if (!found) continue; /* OK, so we really should examine this address. First check whether there is some client here at all! */ if (is_isa || (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) if ((err = found_proc(adapter, addr, -1))) return err; } return 0; }
int inv_mpu_register_slave(struct module *slave_module, struct i2c_client *slave_client, struct ext_slave_platform_data *slave_pdata, struct ext_slave_descr *(*get_slave_descr)(void)) { struct mpu_private_data *mpu = mpu_private_data; struct mldl_cfg *mldl_cfg; struct ext_slave_descr *slave_descr; struct ext_slave_platform_data **pdata_slave; char *irq_name = NULL; int result = 0; if (!slave_client || !slave_pdata || !get_slave_descr) return -EINVAL; if (!mpu) { dev_err(&slave_client->adapter->dev, "%s: Null mpu_private_data\n", __func__); return -EINVAL; } mldl_cfg = &mpu->mldl_cfg; pdata_slave = mldl_cfg->pdata_slave; slave_descr = get_slave_descr(); if (!slave_descr) { dev_err(&slave_client->adapter->dev, "%s: Null ext_slave_descr\n", __func__); return -EINVAL; } mutex_lock(&mpu->mutex); if (mpu->pid) { mutex_unlock(&mpu->mutex); return -EBUSY; } if (pdata_slave[slave_descr->type]) { result = -EBUSY; goto out_unlock_mutex; } slave_pdata->address = slave_client->addr; slave_pdata->irq = slave_client->irq; slave_pdata->adapt_num = i2c_adapter_id(slave_client->adapter); dev_info(&slave_client->adapter->dev, "%s: +%s Type %d: Addr: %2x IRQ: %2d, Adapt: %2d\n", __func__, slave_descr->name, slave_descr->type, slave_pdata->address, slave_pdata->irq, slave_pdata->adapt_num); switch (slave_descr->type) { case EXT_SLAVE_TYPE_ACCEL: irq_name = "accelirq"; break; case EXT_SLAVE_TYPE_COMPASS: irq_name = "compassirq"; break; case EXT_SLAVE_TYPE_PRESSURE: irq_name = "pressureirq"; break; default: irq_name = "none"; }; if (slave_descr->init) { result = slave_descr->init(slave_client->adapter, slave_descr, slave_pdata); if (result) { dev_err(&slave_client->adapter->dev, "%s init failed %d\n", slave_descr->name, result); goto out_unlock_mutex; } } if (slave_descr->type == EXT_SLAVE_TYPE_ACCEL && slave_descr->id == ACCEL_ID_MPU6050 && slave_descr->config) { /* pass a reference to the mldl_cfg data structure to the mpu6050 accel "class" */ struct ext_slave_config config; config.key = MPU_SLAVE_CONFIG_INTERNAL_REFERENCE; config.len = sizeof(struct mldl_cfg *); config.apply = true; config.data = mldl_cfg; result = slave_descr->config( slave_client->adapter, slave_descr, slave_pdata, &config); if (result) { LOG_RESULT_LOCATION(result); goto out_slavedescr_exit; } } pdata_slave[slave_descr->type] = slave_pdata; mpu->slave_modules[slave_descr->type] = slave_module; mldl_cfg->slave[slave_descr->type] = slave_descr; goto out_unlock_mutex; out_slavedescr_exit: if (slave_descr->exit) slave_descr->exit(slave_client->adapter, slave_descr, slave_pdata); out_unlock_mutex: mutex_unlock(&mpu->mutex); if (!result && irq_name && (slave_pdata->irq > 0)) { int warn_result; dev_info(&slave_client->adapter->dev, "Installing %s irq using %d\n", irq_name, slave_pdata->irq); warn_result = slaveirq_init(slave_client->adapter, slave_pdata, irq_name); if (result) dev_WARN(&slave_client->adapter->dev, "%s irq assigned error: %d\n", slave_descr->name, warn_result); } else { dev_WARN(&slave_client->adapter->dev, "%s irq not assigned: %d %d %d\n", slave_descr->name, result, (int)irq_name, slave_pdata->irq); } return result; }
int em28xx_init_camera(struct em28xx *dev) { char clk_name[V4L2_SUBDEV_NAME_SIZE]; struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; struct em28xx_v4l2 *v4l2 = dev->v4l2; int ret = 0; v4l2_clk_name_i2c(clk_name, sizeof(clk_name), i2c_adapter_id(adap), client->addr); v4l2->clk = v4l2_clk_register_fixed(clk_name, -EINVAL); if (IS_ERR(v4l2->clk)) return PTR_ERR(v4l2->clk); switch (dev->em28xx_sensor) { case EM28XX_MT9V011: { struct mt9v011_platform_data pdata; struct i2c_board_info mt9v011_info = { .type = "mt9v011", .addr = client->addr, .platform_data = &pdata, }; v4l2->sensor_xres = 640; v4l2->sensor_yres = 480; /* * FIXME: mt9v011 uses I2S speed as xtal clk - at least with * the Silvercrest cam I have here for testing - for higher * resolutions, a high clock cause horizontal artifacts, so we * need to use a lower xclk frequency. * Yet, it would be possible to adjust xclk depending on the * desired resolution, since this affects directly the * frame rate. */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); v4l2->sensor_xtal = 4300000; pdata.xtal = v4l2->sensor_xtal; if (NULL == v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, &mt9v011_info, NULL)) { ret = -ENODEV; break; } /* probably means GRGB 16 bit bayer */ v4l2->vinmode = 0x0d; v4l2->vinctl = 0x00; break; } case EM28XX_MT9M001: v4l2->sensor_xres = 1280; v4l2->sensor_yres = 1024; em28xx_initialize_mt9m001(dev); /* probably means BGGR 16 bit bayer */ v4l2->vinmode = 0x0c; v4l2->vinctl = 0x00; break; case EM28XX_MT9M111: v4l2->sensor_xres = 640; v4l2->sensor_yres = 512; dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); em28xx_initialize_mt9m111(dev); v4l2->vinmode = 0x0a; v4l2->vinctl = 0x00; break; case EM28XX_OV2640: { struct v4l2_subdev *subdev; struct i2c_board_info ov2640_info = { .type = "ov2640", .flags = I2C_CLIENT_SCCB, .addr = client->addr, .platform_data = &camlink, }; struct v4l2_mbus_framefmt fmt; /* * FIXME: sensor supports resolutions up to 1600x1200, but * resolution setting/switching needs to be modified to * - switch sensor output resolution (including further * configuration changes) * - adjust bridge xclk * - disable 16 bit (12 bit) output formats on high resolutions */ v4l2->sensor_xres = 640; v4l2->sensor_yres = 480; subdev = v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, &ov2640_info, NULL); if (NULL == subdev) { ret = -ENODEV; break; } fmt.code = MEDIA_BUS_FMT_YUYV8_2X8; fmt.width = 640; fmt.height = 480; v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); /* NOTE: for UXGA=1600x1200 switch to 12MHz */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); v4l2->vinmode = 0x08; v4l2->vinctl = 0x00; break; } case EM28XX_NOSENSOR: default: ret = -EINVAL; } if (ret < 0) { v4l2_clk_unregister_fixed(v4l2->clk); v4l2->clk = NULL; } return ret; } EXPORT_SYMBOL_GPL(em28xx_init_camera);
/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ int i2c_detect(struct i2c_adapter *adapter, struct i2c_address_data *address_data, i2c_found_addr_proc * found_proc) { int addr, i, found, j, err; struct i2c_force_data *this_force; int is_isa = i2c_is_isa_adapter(adapter); int adapter_id = is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter); /* Forget it if we can't probe using SMBUS_QUICK */ if ((!is_isa) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) return -1; for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { if ((is_isa && check_region(addr, 1)) || (!is_isa && i2c_check_addr(adapter, addr))) continue; /* If it is in one of the force entries, we don't do any detection at all */ found = 0; for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { for (j = 0; !found && (this_force->force[j] != SENSORS_I2C_END); j += 2) { if ( ((adapter_id == this_force->force[j]) || ((this_force-> force[j] == SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr == this_force->force[j + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n", adapter_id, addr); #endif if ( (err = found_proc(adapter, addr, 0, this_force-> kind))) return err; found = 1; } } } if (found) continue; /* If this address is in one of the ignores, we can forget about it right now */ for (i = 0; !found && (address_data->ignore[i] != SENSORS_I2C_END); i += 2) { if ( ((adapter_id == address_data->ignore[i]) || ((address_data-> ignore[i] == SENSORS_ANY_I2C_BUS) && !is_isa)) && (addr == address_data->ignore[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found ignore parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->ignore_range[i] != SENSORS_I2C_END); i += 3) { if ( ((adapter_id == address_data->ignore_range[i]) || ((address_data-> ignore_range[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr >= address_data->ignore_range[i + 1]) && (addr <= address_data->ignore_range[i + 2])) { #ifdef DEBUG printk ("i2c-proc.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } if (found) continue; /* Now, we will do a detection, but only if it is in the normal or probe entries */ if (is_isa) { for (i = 0; !found && (address_data->normal_isa[i] != SENSORS_ISA_END); i += 1) { if (addr == address_data->normal_isa[i]) { #ifdef DEBUG printk ("i2c-proc.o: found normal isa entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->normal_isa_range[i] != SENSORS_ISA_END); i += 3) { if ((addr >= address_data->normal_isa_range[i]) && (addr <= address_data->normal_isa_range[i + 1]) && ((addr - address_data->normal_isa_range[i]) % address_data->normal_isa_range[i + 2] == 0)) { #ifdef DEBUG printk ("i2c-proc.o: found normal isa_range entry for adapter %d, " "addr %04x", adapter_id, addr); #endif found = 1; } } } else { for (i = 0; !found && (address_data->normal_i2c[i] != SENSORS_I2C_END); i += 1) { if (addr == address_data->normal_i2c[i]) { found = 1; #ifdef DEBUG printk ("i2c-proc.o: found normal i2c entry for adapter %d, " "addr %02x", adapter_id, addr); #endif } } for (i = 0; !found && (address_data->normal_i2c_range[i] != SENSORS_I2C_END); i += 2) { if ((addr >= address_data->normal_i2c_range[i]) && (addr <= address_data->normal_i2c_range[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } } for (i = 0; !found && (address_data->probe[i] != SENSORS_I2C_END); i += 2) { if (((adapter_id == address_data->probe[i]) || ((address_data-> probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr == address_data->probe[i + 1])) { #ifdef DEBUG printk ("i2c-proc.o: found probe parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->probe_range[i] != SENSORS_I2C_END); i += 3) { if ( ((adapter_id == address_data->probe_range[i]) || ((address_data->probe_range[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) && (addr >= address_data->probe_range[i + 1]) && (addr <= address_data->probe_range[i + 2])) { found = 1; #ifdef DEBUG printk ("i2c-proc.o: found probe_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif } } if (!found) continue; /* OK, so we really should examine this address. First check whether there is some client here at all! */ if (is_isa || (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) if ((err = found_proc(adapter, addr, 0, -1))) return err; } return 0; }
static int lm78_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) { int i; struct lm78_data *isa = lm78_data_if_isa(); const char *client_name; struct i2c_adapter *adapter = client->adapter; int address = client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; /* We block updates of the ISA device to minimize the risk of concurrent access to the same LM78 chip through different interfaces. */ if (isa) mutex_lock(&isa->update_lock); if (kind < 0) { if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80) || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address) goto err_nodev; /* Explicitly prevent the misdetection of Winbond chips */ i = i2c_smbus_read_byte_data(client, 0x4f); if (i == 0xa3 || i == 0x5c) goto err_nodev; } /* Determine the chip type. */ if (kind <= 0) { i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID); if (i == 0x00 || i == 0x20 /* LM78 */ || i == 0x40) /* LM78-J */ kind = lm78; else if ((i & 0xfe) == 0xc0) kind = lm79; else { if (kind == 0) dev_warn(&adapter->dev, "Ignoring 'force' " "parameter for unknown chip at " "adapter %d, address 0x%02x\n", i2c_adapter_id(adapter), address); goto err_nodev; } if (lm78_alias_detect(client, i)) { dev_dbg(&adapter->dev, "Device at 0x%02x appears to " "be the same as ISA device\n", address); goto err_nodev; } } if (isa) mutex_unlock(&isa->update_lock); switch (kind) { case lm79: client_name = "lm79"; break; default: client_name = "lm78"; } strlcpy(info->type, client_name, I2C_NAME_SIZE); return 0; err_nodev: if (isa) mutex_unlock(&isa->update_lock); return -ENODEV; }
static void tda8290_init_tuner(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=tda8275_init, .len = 14}; if (priv->ver & TDA8275A) msg.buf = tda8275a_init; tda8290_i2c_bridge(fe, 1); i2c_transfer(priv->i2c_props.adap, &msg, 1); tda8290_i2c_bridge(fe, 0); } /*---------------------------------------------------------------------*/ static void tda829x_release(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; /* only try to release the tuner if we've * attached it from within this module */ if (priv->ver & (TDA18271 | TDA8275 | TDA8275A)) if (fe->ops.tuner_ops.release) fe->ops.tuner_ops.release(fe); kfree(fe->analog_demod_priv); fe->analog_demod_priv = NULL; } static struct tda18271_config tda829x_tda18271_config = { .gate = TDA18271_GATE_ANALOG, }; static int tda829x_find_tuner(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; struct analog_demod_ops *analog_ops = &fe->ops.analog_ops; int i, ret, tuners_found; u32 tuner_addrs; u8 data; struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; if (!analog_ops->i2c_gate_ctrl) { printk(KERN_ERR "tda8290: no gate control were provided!\n"); return -EINVAL; } analog_ops->i2c_gate_ctrl(fe, 1); /* probe for tuner chip */ tuners_found = 0; tuner_addrs = 0; for (i = 0x60; i <= 0x63; i++) { msg.addr = i; ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); if (ret == 1) { tuners_found++; tuner_addrs = (tuner_addrs << 8) + i; } } /* if there is more than one tuner, we expect the right one is behind the bridge and we choose the highest address that doesn't give a response now */ analog_ops->i2c_gate_ctrl(fe, 0); if (tuners_found > 1) for (i = 0; i < tuners_found; i++) { msg.addr = tuner_addrs & 0xff; ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); if (ret == 1) tuner_addrs = tuner_addrs >> 8; else break; } if (tuner_addrs == 0) { tuner_addrs = 0x60; tuner_info("could not clearly identify tuner address, " "defaulting to %x\n", tuner_addrs); } else { tuner_addrs = tuner_addrs & 0xff; tuner_info("setting tuner address to %x\n", tuner_addrs); } priv->tda827x_addr = tuner_addrs; msg.addr = tuner_addrs; analog_ops->i2c_gate_ctrl(fe, 1); ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); if (ret != 1) { tuner_warn("tuner access failed!\n"); analog_ops->i2c_gate_ctrl(fe, 0); return -EREMOTEIO; } if ((data == 0x83) || (data == 0x84)) { priv->ver |= TDA18271; tda829x_tda18271_config.config = priv->cfg.config; dvb_attach(tda18271_attach, fe, priv->tda827x_addr, priv->i2c_props.adap, &tda829x_tda18271_config); } else { if ((data & 0x3c) == 0) priv->ver |= TDA8275; else priv->ver |= TDA8275A; dvb_attach(tda827x_attach, fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg); priv->cfg.switch_addr = priv->i2c_props.addr; } if (fe->ops.tuner_ops.init) fe->ops.tuner_ops.init(fe); if (fe->ops.tuner_ops.sleep) fe->ops.tuner_ops.sleep(fe); analog_ops->i2c_gate_ctrl(fe, 0); return 0; } static int tda8290_probe(struct tuner_i2c_props *i2c_props) { #define TDA8290_ID 0x89 unsigned char tda8290_id[] = { 0x1f, 0x00 }; /* detect tda8290 */ tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); if (tda8290_id[1] == TDA8290_ID) { if (debug) printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", __func__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); return 0; } return -ENODEV; }
static int pixter_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pixter_device *dev; const struct atomisp_camera_caps *caps = NULL; char *pixter_name = NULL; struct pixter_setting *settings; struct pixter_dbgfs_data *dbgfs_data; u32 reg_val, i, j; int ret; /* allocate sensor device & init sub device */ dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; mutex_init(&dev->input_lock); dev->dbg_timing.mipi_clk = PIXTER_DEF_CLOCK; v4l2_i2c_subdev_init(&dev->sd, client, &pixter_ops); if (client->dev.platform_data) { dev->platform_data = client->dev.platform_data; ret = dev->platform_data->csi_cfg(&dev->sd, 1); if (ret) goto out_free; if (dev->platform_data->get_camera_caps) caps = dev->platform_data->get_camera_caps(); else caps = atomisp_get_default_camera_caps(); dev->caps = caps; } dev->mipi_info = v4l2_get_subdev_hostdata(&dev->sd); if (!dev->mipi_info) { dev_err(&client->dev, "Faild to get mipi info.\n"); goto out_free; } /* Get the number of mipi lanes */ dev->dbg_timing.mipi_lanes_num = dev->mipi_info->num_lanes; dev->regmap = devm_regmap_init_i2c(client, &pixter_reg_config); if (IS_ERR(dev->regmap)) { ret = PTR_ERR(dev->regmap); dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); goto out_free; } /* Load Pixter settings */ pixter_write_reg(&dev->sd, PIXTER_SDRAM_BASE, 0); pixter_read_reg(&dev->sd, PIXTER_MAGIC_ADDR, ®_val); if (reg_val != PIXTER_MAGIC) { dev_err(&client->dev, "PIXTER magic does not match. Got 0x%X\n", reg_val); ret = -EIO; goto out_free; } pixter_read_reg(&dev->sd, PIXTER_SETTING_NUM, &dev->setting_num); dev->settings = devm_kzalloc(&client->dev, sizeof(struct pixter_setting) * dev->setting_num, GFP_KERNEL); if (!dev->settings) { dev_err(&client->dev, "OOM when allocating settings.\n"); ret = -ENOMEM; goto out_free; } settings = dev->settings; ret = pixter_read_buf(&dev->sd, PIXTER_SETTING_START, sizeof(struct pixter_setting) * dev->setting_num, settings); if (ret) { dev_err(&client->dev, "Failed to read Pixter settings\n"); goto out_free; } /* Find settings that match the current device. */ for (i = 0, j = 0; i < dev->setting_num; i++) { if (caps->sensor[0].stream_num == settings[i].valid_vc_num) settings[j++] = settings[i]; } dev->setting_num = j; dev_info(&client->dev, "Setting num=%d\n", dev->setting_num); if (!dev->setting_num) { dev_err(&client->dev, "No matched settings loaded.\n"); ret = -ENODEV; goto out_free; } dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; dev->pad.flags = MEDIA_PAD_FL_SOURCE; dev->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; dev->format.code = format_bridge[ settings[0].vc[settings[0].def_vc].format].v4l2_format; /* * sd->name is updated with sensor driver name by the v4l2. * change it to sensor name in this case. */ if (dev->mipi_info->port == ATOMISP_CAMERA_PORT_PRIMARY) pixter_name = PIXTER_0; else if(dev->mipi_info->port == ATOMISP_CAMERA_PORT_SECONDARY) pixter_name = PIXTER_1; else pixter_name = PIXTER_2; snprintf(dev->sd.name, sizeof(dev->sd.name), "%s %d-%04x", pixter_name, i2c_adapter_id(client->adapter), client->addr); dev_info(&client->dev, "%s dev->sd.name: %s\n", __func__, dev->sd.name); dev->sd.entity.ops = &pixter_entity_ops; dev->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, ARRAY_SIZE(ctrls)); if (ret) goto out_free; for (i = 0; i < ARRAY_SIZE(ctrls); i++) v4l2_ctrl_new_custom(&dev->ctrl_handler, &ctrls[i], NULL); if (dev->ctrl_handler.error) { ret = -EINVAL; goto out_free; } /* Use same lock for controls as for everything else. */ dev->ctrl_handler.lock = &dev->input_lock; dev->sd.ctrl_handler = &dev->ctrl_handler; v4l2_ctrl_handler_setup(&dev->ctrl_handler); ret = media_entity_init(&dev->sd.entity, 1, &dev->pad, 0); if (ret) goto out_free; /* Create debugfs nodes. */ dev->dbgfs_data = devm_kzalloc(&client->dev, sizeof(struct pixter_dbgfs_data) * (ARRAY_SIZE(dbgfs) + dev->setting_num + 1), GFP_KERNEL); if (!dev->dbgfs_data) goto out_free; dbgfs_data = dev->dbgfs_data; dbgfs_data[0].entry = debugfs_create_dir(pixter_name, NULL); for (i = 1; i < ARRAY_SIZE(dbgfs); i++) { struct dentry *parent; for (j = 0; j < i; j++) { if (!strcmp(dbgfs[i].parent, dbgfs[j].name)) break; } if (j == i) continue; parent = dbgfs_data[j].entry; dbgfs_data[i].dev = dev; dbgfs_data[i].ptr = (u8*)dev + dbgfs[i].offset; if (dbgfs[i].type == DBGFS_DIR) dbgfs_data[i].entry = debugfs_create_dir(dbgfs[i].name, parent); else dbgfs_data[i].entry = debugfs_create_file(dbgfs[i].name, dbgfs[i].mode, parent, &dbgfs_data[i], &pixter_dbgfs_fops); } /* Create setting nodes. */ dev->setting_en = devm_kzalloc(&client->dev, sizeof(u32) * dev->setting_num, GFP_KERNEL); if (!dev->setting_en) goto out_free; dbgfs_data[i].entry = debugfs_create_dir("settings", dbgfs_data[0].entry); for (j = 0; j < dev->setting_num; j++) { char setting_name[32]; u32 idx = i + j + 1; struct pixter_vc_setting *vc = &settings[j].vc[settings[j].def_vc]; dev->setting_en[j] = 1; snprintf(setting_name, 32, "%d.%dx%d_%s@%d", j, vc->width, vc->height, format_bridge[vc->format].name, vc->fps); dbgfs_data[idx].dev = dev; dbgfs_data[idx].ptr = &dev->setting_en[j]; dbgfs_data[idx].entry = debugfs_create_file(setting_name, S_IRUSR|S_IWUSR, dbgfs_data[i].entry, &dbgfs_data[idx], &pixter_dbgfs_fops); } pixter_read_mipi_timing(&dev->sd); return 0; out_free: pixter_remove(client); return ret; }
static int adm1025_detect(struct i2c_adapter *adapter, int address, unsigned short flags, int kind) { int i; struct i2c_client *new_client; struct adm1025_data *data; int err = 0; const char *type_name = ""; const char *client_name = ""; /* Make sure we aren't probing the ISA bus!! This is just a safety check at this moment; i2c_detect really won't call us. */ #ifdef DEBUG if (i2c_is_isa_adapter(adapter)) { printk ("adm1025.o: adm1025_detect called for an ISA bus adapter?!?\n"); return 0; } #endif if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) goto ERROR0; /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access adm1025_{read,write}_value. */ if (!(new_client = kmalloc(sizeof(struct i2c_client) + sizeof(struct adm1025_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } data = (struct adm1025_data *) (new_client + 1); new_client->addr = address; new_client->data = data; new_client->adapter = adapter; new_client->driver = &adm1025_driver; new_client->flags = 0; /* Now, we do the remaining detection. */ if (kind < 0) { if((adm1025_read_value(new_client,ADM1025_REG_CONFIG) & 0x80) != 0x00) goto ERROR1; } /* Determine the chip type. */ if (kind <= 0) { i = adm1025_read_value(new_client, ADM1025_REG_COMPANY_ID); if (i == 0x41) kind = adm1025; else { if (kind == 0) printk ("adm1025.o: Ignoring 'force' parameter for unknown chip at " "adapter %d, address 0x%02x\n", i2c_adapter_id(adapter), address); goto ERROR1; } } if (kind == adm1025) { type_name = "adm1025"; client_name = "ADM1025 chip"; } else { #ifdef DEBUG printk("adm1025.o: Internal error: unknown kind (%d)?!?", kind); #endif goto ERROR1; } /* Fill in the remaining client fields and put it into the global list */ strcpy(new_client->name, client_name); data->type = kind; new_client->id = adm1025_id++; data->valid = 0; init_MUTEX(&data->update_lock); /* Tell the I2C layer a new client has arrived */ if ((err = i2c_attach_client(new_client))) goto ERROR3; /* Register a new directory entry with module sensors */ if ((i = i2c_register_entry(new_client, type_name, adm1025_dir_table_template, THIS_MODULE)) < 0) { err = i; goto ERROR4; } data->sysctl_id = i; /* Initialize the ADM1025 chip */ adm1025_init_client(new_client); return 0; /* OK, this is not exactly good programming practice, usually. But it is very code-efficient in this case. */ ERROR4: i2c_detach_client(new_client); ERROR3: ERROR1: kfree(new_client); ERROR0: return err; }
static int gc_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct gc_device *dev; int ret; /* allocate sensor device & init sub device */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { v4l2_err(client, "%s: out of memory\n", __func__); return -ENOMEM; } mutex_init(&dev->input_lock); dev->fmt_idx = 0; v4l2_info(client, "i2c name: %s\n", client->name); dev->product_info = (struct gc_product_info *)&gc0310_product_info; if (dev->product_info == NULL) { v4l2_err(client, "product_info was null\n"); ret = -ENODEV; goto out_free; } /* [WR]Set default res table */ dev->curr_res_table = dev->product_info->mode_info->res_video; dev->entries_curr_table = dev->product_info->mode_info->n_res_video; dev->streaming = 0; dev->power = 0; v4l2_i2c_subdev_init(&(dev->sd), client, &gc_ops); ret = pltfrm_camera_module_init(&(dev->sd), &(dev->pltfrm_data)); if (ret) { pltfrm_camera_module_pr_err(&(dev->sd), "failed with error %d\n", ret); goto out_pltfrm_data_free; } pltfrm_camera_module_pr_debug(&(dev->sd), "%s %d-%04x\n", dev->product_info->name, i2c_adapter_id(client->adapter), client->addr); ret = gc_s_power(&dev->sd, 1); if (ret != 0) { pltfrm_camera_module_pr_err(&(dev->sd), "failed with error %d\n", ret); goto power_up_error; } /* Query device specifics */ ret = query_device_specifics(dev); if (ret != 0) { pltfrm_camera_module_pr_err(&(dev->sd), "failed with error %d\n", ret); goto power_up_error; } gc_s_power(&dev->sd, 0); #if 0 /* Initialize v4l2 control handler */ ret = __gc_init_ctrl_handler(dev); if (ret) goto out_ctrl_handler_free; dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; dev->pad.flags = MEDIA_PAD_FL_SOURCE; dev->format.code = V4L2_MBUS_FMT_UYVY8_2X8; #if defined(CONFIG_MEDIA_CONTROLLER) dev->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&dev->sd.entity, 1, &dev->pad, 0); #endif if (ret) gc_remove(client); #endif return ret; #if 0 out_ctrl_handler_free: v4l2_ctrl_handler_free(&dev->ctrl_handler); #endif power_up_error: pltfrm_camera_module_release(&dev->sd); out_pltfrm_data_free: devm_kfree(&(client->dev), dev->pltfrm_data); out_free: v4l2_device_unregister_subdev(&dev->sd); kfree(dev); return ret; }