コード例 #1
0
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;
}
コード例 #2
0
ファイル: tda18271-fe.c プロジェクト: 125radheyshyam/linux
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;
}
コード例 #3
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;
}
コード例 #4
0
ファイル: i2c-mux-reg.c プロジェクト: 513855417/linux
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++;
	}
コード例 #5
0
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;
}
コード例 #6
0
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);
}
コード例 #7
0
ファイル: lis3lv02d_i2c.c プロジェクト: robacklin/ts4700
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);
}
コード例 #8
0
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;
}
コード例 #9
0
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;
}
コード例 #10
0
/**
 * 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;
	}
}
コード例 #11
0
ファイル: v4l2-common.c プロジェクト: beam/linux-tbs-drivers
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);
}
コード例 #12
0
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);
}
コード例 #13
0
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);
}
コード例 #14
0
ファイル: i2c-proc.c プロジェクト: liexusong/Linux-2.4.16
/* 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;
}
コード例 #15
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;
}
コード例 #16
0
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++;
	}
コード例 #17
0
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;
}
コード例 #18
0
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;
}
コード例 #19
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;
}
コード例 #20
0
/* 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;
}
コード例 #21
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;
}
コード例 #22
0
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);
コード例 #23
0
ファイル: i2c-proc.c プロジェクト: liexusong/Linux-2.4.16
/* 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;
}
コード例 #24
0
ファイル: lm78.c プロジェクト: 285452612/ali_kernel
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;
}
コード例 #25
0
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;
}
コード例 #26
0
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, &reg_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;
}
コード例 #27
0
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;
}
コード例 #28
0
ファイル: gc_0310.c プロジェクト: tinocyngn/sofia-kernel
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;
}