static int attach_inform(struct i2c_client *client)
{
	struct saa7134_dev *dev = client->adapter->algo_data;
	int tuner = dev->tuner_type;
	struct tuner_setup tun_setup;

	d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
		client->driver->driver.name, client->addr, client->name);

	/* Am I an i2c remote control? */

	switch (client->addr) {
		case 0x7a:
		case 0x47:
		case 0x71:
		case 0x2d:
		{
			struct IR_i2c *ir = i2c_get_clientdata(client);
			d1printk("%s i2c IR detected (%s).\n",
				 client->driver->driver.name, ir->phys);
			saa7134_set_i2c_ir(dev,ir);
			break;
		}
	}

	if (!client->driver->command)
		return 0;

	if (saa7134_boards[dev->board].radio_type != UNSET) {

		tun_setup.type = saa7134_boards[dev->board].radio_type;
		tun_setup.addr = saa7134_boards[dev->board].radio_addr;

		if ((tun_setup.addr == ADDR_UNSET) || (tun_setup.addr == client->addr)) {
			tun_setup.mode_mask = T_RADIO;

			client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
		}
	}

	if (tuner != UNSET) {
		tun_setup.type = tuner;
		tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
		tun_setup.config = saa7134_boards[dev->board].tuner_config;
		tun_setup.tuner_callback = saa7134_tuner_callback;

		if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {

			tun_setup.mode_mask = T_ANALOG_TV;

			client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
		}

		if (tuner == TUNER_TDA9887) {
			struct v4l2_priv_tun_config tda9887_cfg;

			tda9887_cfg.tuner = TUNER_TDA9887;
			tda9887_cfg.priv = &dev->tda9887_conf;

			client->driver->command(client, TUNER_SET_CONFIG,
						&tda9887_cfg);
		}
	}


	return 0;
}
示例#2
0
/* turn on/off nicam + stereo */
void msp3400c_setstereo(struct i2c_client *client, int mode)
{
	static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
	struct msp_state *state = i2c_get_clientdata(client);
	int nicam = 0;		/* channel source: FM/AM or nicam */
	int src = 0;

	if (state->opmode == OPMODE_AUTOSELECT) {
		/* this method would break everything, let's make sure
		 * it's never called
		 */
		v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
		     mode);
		return;
	}

	/* switch demodulator */
	switch (state->mode) {
	case MSP_MODE_FM_TERRA:
		v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[mode]);
		msp3400c_setcarrier(client, state->second, state->main);
		switch (mode) {
		case V4L2_TUNER_MODE_STEREO:
			msp_write_dsp(client, 0x000e, 0x3001);
			break;
		case V4L2_TUNER_MODE_MONO:
		case V4L2_TUNER_MODE_LANG1:
		case V4L2_TUNER_MODE_LANG2:
			msp_write_dsp(client, 0x000e, 0x3000);
			break;
		}
		break;
	case MSP_MODE_FM_SAT:
		v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[mode]);
		switch (mode) {
		case V4L2_TUNER_MODE_MONO:
			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
			break;
		case V4L2_TUNER_MODE_STEREO:
			msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
			break;
		case V4L2_TUNER_MODE_LANG1:
			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
			break;
		case V4L2_TUNER_MODE_LANG2:
			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
			break;
		}
		break;
	case MSP_MODE_FM_NICAM1:
	case MSP_MODE_FM_NICAM2:
	case MSP_MODE_AM_NICAM:
		v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[mode]);
		msp3400c_setcarrier(client,state->second,state->main);
		if (state->nicam_on)
			nicam=0x0100;
		break;
	case MSP_MODE_BTSC:
		v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[mode]);
		nicam=0x0300;
		break;
	case MSP_MODE_EXTERN:
		v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[mode]);
		nicam = 0x0200;
		break;
	case MSP_MODE_FM_RADIO:
		v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[mode]);
		break;
	default:
		v4l_dbg(1, msp_debug, client, "mono setstereo\n");
		return;
	}

	/* switch audio */
	switch (mode) {
	case V4L2_TUNER_MODE_STEREO:
		src = 0x0020 | nicam;
		break;
	case V4L2_TUNER_MODE_MONO:
		if (state->mode == MSP_MODE_AM_NICAM) {
			v4l_dbg(1, msp_debug, client, "switching to AM mono\n");
			/* AM mono decoding is handled by tuner, not MSP chip */
			/* SCART switching control register */
			msp_set_scart(client, SCART_MONO, 0);
			src = 0x0200;
			break;
		}
	case V4L2_TUNER_MODE_LANG1:
		src = 0x0000 | nicam;
		break;
	case V4L2_TUNER_MODE_LANG2:
		src = 0x0010 | nicam;
		break;
	}
	v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src);

	if (msp_dolby) {
		msp_write_dsp(client, 0x0008, 0x0520);
		msp_write_dsp(client, 0x0009, 0x0620);
		msp_write_dsp(client, 0x000a, src);
		msp_write_dsp(client, 0x000b, src);
	} else {
		msp_write_dsp(client, 0x0008, src);
		msp_write_dsp(client, 0x0009, src);
		msp_write_dsp(client, 0x000a, src);
		msp_write_dsp(client, 0x000b, src);
		msp_write_dsp(client, 0x000c, src);
		if (state->has_scart23_in_scart2_out)
			msp_write_dsp(client, 0x0041, src);
	}
}
示例#3
0
static ssize_t bma250_fast_calibration_z_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long data;
	signed char tmp;
	unsigned int timeout = 0;
	int error;
	struct i2c_client *client = to_i2c_client(dev);
	struct bma250_data *bma250 = i2c_get_clientdata(client);

	struct bma250acc acc_cal;
	struct bma250acc acc_cal_pre;

	error = strict_strtoul(buf, 10, &data);
	if (error)
		return error;

	bma250_read_accel_xyz(bma250->bma250_client, &acc_cal_pre);
	mdelay(50);

	if (bma250_set_offset_target_z(bma250->bma250_client, (unsigned char)data) < 0)
		return -EINVAL;

	if (bma250_set_cal_trigger(bma250->bma250_client, 3) < 0)
		return -EINVAL;

		atomic_set(&bma250->fast_calib_z_rslt, 0);

	do {
		mdelay(2);
		bma250_get_cal_ready(bma250->bma250_client, &tmp);

		bma250_read_accel_xyz(bma250->bma250_client, &acc_cal);

		if( (tmp == 0)	&&
			((abs(acc_cal.x - acc_cal_pre.x) > BMA250_SHAKING_DETECT_THRESHOLD)
				|| (abs((acc_cal.y - acc_cal_pre.y)) > BMA250_SHAKING_DETECT_THRESHOLD)
				|| (abs((acc_cal.z - acc_cal_pre.z)) > BMA250_SHAKING_DETECT_THRESHOLD))
		  )
		{
			printk(KERN_INFO "fast calibration for z-axis is failed due to BMA250_SHAKING\n");
			printk(KERN_INFO "(%d, %d), (%d, %d), (%d, %d)\n", acc_cal.x, acc_cal_pre.x, acc_cal.y, acc_cal_pre.y, acc_cal.z, acc_cal_pre.z);
			return count;
		}
		else
		{
			acc_cal_pre.x = acc_cal.x;
			acc_cal_pre.y = acc_cal.y;
			acc_cal_pre.z = acc_cal.z;
		}

		printk(KERN_INFO "wait 2ms and got cal ready flag is %d\n", tmp);
		timeout++;
		if (timeout == 1000) {
			printk(KERN_INFO "get fast calibration ready error\n");
			return -EINVAL;
		}

	} while (tmp == 0);

	atomic_set(&bma250->fast_calib_z_rslt, 1);

	printk(KERN_INFO "z axis fast calibration finished\n");
	return count;
}
示例#4
0
static struct lm63_data *lm63_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);

	mutex_lock(&data->update_lock);

	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
		if (data->config & 0x04) { /* tachometer enabled  */
			/* order matters for fan1_input */
			data->fan[0] = i2c_smbus_read_byte_data(client,
				       LM63_REG_TACH_COUNT_LSB) & 0xFC;
			data->fan[0] |= i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_COUNT_MSB) << 8;
			data->fan[1] = (i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_LIMIT_LSB) & 0xFC)
				     | (i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_LIMIT_MSB) << 8);
		}

		data->pwm1_freq = i2c_smbus_read_byte_data(client,
				  LM63_REG_PWM_FREQ);
		if (data->pwm1_freq == 0)
			data->pwm1_freq = 1;
		data->pwm1_value = i2c_smbus_read_byte_data(client,
				   LM63_REG_PWM_VALUE);

		data->temp8[0] = i2c_smbus_read_byte_data(client,
				 LM63_REG_LOCAL_TEMP);
		data->temp8[1] = i2c_smbus_read_byte_data(client,
				 LM63_REG_LOCAL_HIGH);

		/* order matters for temp2_input */
		data->temp11[0] = i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_TEMP_MSB) << 8;
		data->temp11[0] |= i2c_smbus_read_byte_data(client,
				   LM63_REG_REMOTE_TEMP_LSB);
		data->temp11[1] = (i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_LOW_MSB) << 8)
				| i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_LOW_LSB);
		data->temp11[2] = (i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_HIGH_MSB) << 8)
				| i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_HIGH_LSB);
		data->temp8[2] = i2c_smbus_read_byte_data(client,
				 LM63_REG_REMOTE_TCRIT);
		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
					LM63_REG_REMOTE_TCRIT_HYST);

		data->alarms = i2c_smbus_read_byte_data(client,
			       LM63_REG_ALERT_STATUS) & 0x7F;

		data->last_updated = jiffies;
		data->valid = 1;
	}

	mutex_unlock(&data->update_lock);

	return data;
}
示例#5
0
static long mma8452_ioctl( struct file *file, unsigned int cmd,unsigned long arg)
{

	void __user *argp = (void __user *)arg;
	// char msg[RBUFF_SIZE + 1];
    struct mma8452_axis sense_data = {0};
	int ret = -1;
	char rate;
	struct i2c_client *client = container_of(mma8452_device.parent, struct i2c_client, dev);
    struct mma8452_data* this = (struct mma8452_data *)i2c_get_clientdata(client);  /* 设备数据实例的指针. */

	switch (cmd) {
	case MMA_IOCTL_APP_SET_RATE:
		if (copy_from_user(&rate, argp, sizeof(rate)))
			return -EFAULT;
		break;
	default:
		break;
	}

	switch (cmd) {
	case MMA_IOCTL_START:
        mutex_lock(&(this->operation_mutex) );
        mmaprintkd("to perform 'MMA_IOCTL_START', former 'start_count' is %d.", this->start_count);
        (this->start_count)++;
        if ( 1 == this->start_count ) {
            atomic_set(&(this->data_ready), 0);
            if ( (ret = mma8452_start(client, MMA8452_RATE_12P5) ) < 0 ) {
                mutex_unlock(&(this->operation_mutex) );
                return ret;
            }
        }
        mutex_unlock(&(this->operation_mutex) );
        mmaprintkd("finish 'MMA_IOCTL_START', ret = %d.", ret);
        return 0;

	case MMA_IOCTL_CLOSE:
        mutex_lock(&(this->operation_mutex) );
        mmaprintkd("to perform 'MMA_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", this->start_count, get_current()->pid);
        if ( 0 == (--(this->start_count) ) ) {
            atomic_set(&(this->data_ready), 0);
            if ( (ret = mma8452_close(client) ) < 0 ) {
                mutex_unlock(&(this->operation_mutex) );
                return ret;
            }
        }
        mutex_unlock(&(this->operation_mutex) );
        return 0;

	case MMA_IOCTL_APP_SET_RATE:
		ret = mma8452_reset_rate(client, rate);
		if (ret < 0)
			return ret;
		break;
	case MMA_IOCTL_GETDATA:
		// ret = mma8452_trans_buff(msg, RBUFF_SIZE);
		if ( (ret = mma8452_get_cached_data(client, &sense_data) ) < 0 ) {
            printk("failed to get cached sense data, ret = %d.", ret);
			return ret;
        }
		break;
	default:
		return -ENOTTY;
	}

	switch (cmd) {
	case MMA_IOCTL_GETDATA:
        /*
		if (copy_to_user(argp, &msg, sizeof(msg)))
			return -EFAULT;
        */
        if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) ) {
            printk("failed to copy sense data to user space.");
			return -EFAULT;
        }
		break;
	default:
		break;
	}

	return 0;
}
示例#6
0
static int bma023_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct bma023_data *bma023 = file->private_data;
	int try;
	int err = 0;
	unsigned char data[6];

	switch (cmd) {
	case BMA023_CALIBRATION:
		if (copy_from_user((struct acceleration *)data,
			(struct acceleration *)arg, 6) != 0) {
			pr_err("copy_from_user error\n");
			return -EFAULT;
		}
		/* iteration time = 20 */
		try = 20;
		err = bma023_calibrate(bma023,
				*(struct acceleration *)data, &try);
		break;
	default:
		break;
	}
	return 0;
}

static const struct file_operations bma023_fops = {
	.owner = THIS_MODULE,
	.open = bma023_open,
	.release = bma023_close,
	.ioctl = bma023_ioctl,
};

static int bma023_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct bma023_data *bma023;
	int err;

	/* setup private data */
	bma023 = kzalloc(sizeof(struct bma023_data), GFP_KERNEL);
	if (!bma023)
		return -ENOMEM;
	mutex_init(&bma023->enable_mutex);
	mutex_init(&bma023->data_mutex);

	/* setup i2c client */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		err = -ENODEV;
		goto err_i2c_fail;
	}
	i2c_set_clientdata(client, bma023);
	bma023->client = client;

	/* detect and init hardware */
	err = bma023_detect(client, NULL);
	if (err)
		goto err_id_read;
	dev_info(&client->dev, "%s found\n", id->name);
	dev_info(&client->dev, "al_version=%d, ml_version=%d\n",
		 bma023_read_bits(bma023, BMA023_AL_VERSION),
		 bma023_read_bits(bma023, BMA023_ML_VERSION));

	bma023_hw_init(bma023);
	bma023_set_delay(&client->dev, BMA023_DEFAULT_DELAY);

	/* setup driver interfaces */
	INIT_DELAYED_WORK(&bma023->work, bma023_work_func);

	err = bma023_input_init(bma023);
	if (err < 0)
		goto err_input_allocate;

	err = sysfs_create_group(&bma023->input->dev.kobj,
					&bma023_attribute_group);
	if (err < 0)
		goto err_sys_create;

	bma023->bma023_device.minor = MISC_DYNAMIC_MINOR;
	bma023->bma023_device.name = "accelerometer";
	bma023->bma023_device.fops = &bma023_fops;

	err = misc_register(&bma023->bma023_device);
	if (err) {
		pr_err("%s: misc_register failed\n", __FILE__);
		goto err_misc_register;
	}

	/* filter init */
	filter_init(bma023);

	return 0;

err_misc_register:
	sysfs_remove_group(&bma023->input->dev.kobj,
				&bma023_attribute_group);
err_sys_create:
	bma023_input_fini(bma023);
err_input_allocate:
err_id_read:
err_i2c_fail:
	kfree(bma023);
	return err;
}

static int bma023_remove(struct i2c_client *client)
{
	struct bma023_data *bma023 = i2c_get_clientdata(client);

	bma023_set_enable(&client->dev, 0);

	sysfs_remove_group(&bma023->input->dev.kobj, &bma023_attribute_group);
	bma023_input_fini(bma023);
	kfree(bma023);

	return 0;
}

static int bma023_suspend(struct device *dev)
{
	struct bma023_data *bma023 = dev_get_drvdata(dev);

	mutex_lock(&bma023->enable_mutex);
	if (bma023_get_enable(dev)) {
		cancel_delayed_work_sync(&bma023->work);
		bma023_power_down(bma023);
	}
	mutex_unlock(&bma023->enable_mutex);

	return 0;
}

static int bma023_resume(struct device *dev)
{
	struct bma023_data *bma023 = dev_get_drvdata(dev);
	int delay = atomic_read(&bma023->delay);

	bma023_hw_init(bma023);
	bma023_set_delay(dev, delay);

	mutex_lock(&bma023->enable_mutex);
	if (bma023_get_enable(dev)) {
		bma023_power_up(bma023);
		schedule_delayed_work(&bma023->work,
				      delay_to_jiffies(delay) + 1);
	}
	mutex_unlock(&bma023->enable_mutex);

	return 0;
}

static const struct dev_pm_ops bma023_pm_ops = {
	.suspend = bma023_suspend,
	.resume = bma023_resume,
};

static const struct i2c_device_id bma023_id[] = {
	{BMA023_NAME, 0},
	{},
};

MODULE_DEVICE_TABLE(i2c, bma023_id);

struct i2c_driver bma023_driver = {
	.driver = {
		.name = "bma023",
		.owner = THIS_MODULE,
		.pm = &bma023_pm_ops,
	},
	.probe = bma023_probe,
	.remove = bma023_remove,
	.id_table = bma023_id,
};
示例#7
0
static int
saa7185_command (struct i2c_client *client,
		 unsigned int       cmd,
		 void              *arg)
{
	struct saa7185 *encoder = i2c_get_clientdata(client);

	switch (cmd) {

	case 0:
		saa7185_write_block(client, init_common,
				    sizeof(init_common));
		switch (encoder->norm) {

		case VIDEO_MODE_NTSC:
			saa7185_write_block(client, init_ntsc,
					    sizeof(init_ntsc));
			break;

		case VIDEO_MODE_PAL:
			saa7185_write_block(client, init_pal,
					    sizeof(init_pal));
			break;
		}

		break;

	case ENCODER_GET_CAPABILITIES:
	{
		struct video_encoder_capability *cap = arg;

		cap->flags =
		    VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
		    VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
		cap->inputs = 1;
		cap->outputs = 1;
	}
		break;

	case ENCODER_SET_NORM:
	{
		int *iarg = arg;

		//saa7185_write_block(client, init_common, sizeof(init_common));

		switch (*iarg) {

		case VIDEO_MODE_NTSC:
			saa7185_write_block(client, init_ntsc,
					    sizeof(init_ntsc));
			break;

		case VIDEO_MODE_PAL:
			saa7185_write_block(client, init_pal,
					    sizeof(init_pal));
			break;

		case VIDEO_MODE_SECAM:
		default:
			return -EINVAL;

		}
		encoder->norm = *iarg;
	}
		break;

	case ENCODER_SET_INPUT:
	{
		int *iarg = arg;

		/* RJ: *iarg = 0: input is from SA7111
		 *iarg = 1: input is from ZR36060 */

		switch (*iarg) {

		case 0:
			/* Switch RTCE to 1 */
			saa7185_write(client, 0x61,
				      (encoder->reg[0x61] & 0xf7) | 0x08);
			saa7185_write(client, 0x6e, 0x01);
			break;

		case 1:
			/* Switch RTCE to 0 */
			saa7185_write(client, 0x61,
				      (encoder->reg[0x61] & 0xf7) | 0x00);
			/* SW: a slight sync problem... */
			saa7185_write(client, 0x6e, 0x00);
			break;

		default:
			return -EINVAL;

		}
	}
		break;

	case ENCODER_SET_OUTPUT:
	{
		int *iarg = arg;

		/* not much choice of outputs */
		if (*iarg != 0) {
			return -EINVAL;
		}
	}
		break;

	case ENCODER_ENABLE_OUTPUT:
	{
		int *iarg = arg;

		encoder->enable = !!*iarg;
		saa7185_write(client, 0x61,
			      (encoder->reg[0x61] & 0xbf) |
			      (encoder->enable ? 0x00 : 0x40));
	}
		break;

	default:
		return -EINVAL;
	}

	return 0;
}
示例#8
0
static void lis3dh_resume(struct early_suspend *h)
{
	struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev);
  struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client);
	lis3dh_start_dev(client,lis3dh->curr_tate);
}
示例#9
0
/*
 * Ideally we shouldn't have to initialize anything, since the BIOS
 * should have taken care of everything
 */
static void lm63_init_client(struct i2c_client *client)
{
	struct lm63_data *data = i2c_get_clientdata(client);
	u8 convrate;

	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
	data->config_fan = i2c_smbus_read_byte_data(client,
						    LM63_REG_CONFIG_FAN);

	/* Start converting if needed */
	if (data->config & 0x40) { /* standby */
		dev_dbg(&client->dev, "Switching to operational mode\n");
		data->config &= 0xA7;
		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
					  data->config);
	}
	/* Tachometer is always enabled on LM64 */
	if (data->kind == lm64)
		data->config |= 0x04;

	/* We may need pwm1_freq before ever updating the client data */
	data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
	if (data->pwm1_freq == 0)
		data->pwm1_freq = 1;

	switch (data->kind) {
	case lm63:
	case lm64:
		data->max_convrate_hz = LM63_MAX_CONVRATE_HZ;
		data->lut_size = 8;
		break;
	case lm96163:
		data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ;
		data->lut_size = 12;
		data->trutherm
		  = i2c_smbus_read_byte_data(client,
					     LM96163_REG_TRUTHERM) & 0x02;
		break;
	}
	convrate = i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE);
	if (unlikely(convrate > LM63_MAX_CONVRATE))
		convrate = LM63_MAX_CONVRATE;
	data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz,
						convrate);

	/*
	 * For LM96163, check if high resolution PWM
	 * and unsigned temperature format is enabled.
	 */
	if (data->kind == lm96163) {
		u8 config_enhanced
		  = i2c_smbus_read_byte_data(client,
					     LM96163_REG_CONFIG_ENHANCED);
		if (config_enhanced & 0x20)
			data->lut_temp_highres = true;
		if ((config_enhanced & 0x10)
		    && !(data->config_fan & 0x08) && data->pwm1_freq == 8)
			data->pwm_highres = true;
		if (config_enhanced & 0x08)
			data->remote_unsigned = true;
	}

	/* Show some debug info about the LM63 configuration */
	if (data->kind == lm63)
		dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
			(data->config & 0x04) ? "tachometer input" :
			"alert output");
	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
		(data->config_fan & 0x08) ? "1.4" : "360",
		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
		(data->config_fan & 0x10) ? "low" : "high",
		(data->config_fan & 0x20) ? "manual" : "auto");
}
示例#10
0
static long lis3dh_ioctl(struct file *file, unsigned int cmd,unsigned long arg)
{
	int liRet = -1;
	char rate;
	void __user *argp = (void __user *)arg;
	
    struct lis3dh_axis sense_data = {0};
	struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev);
    struct lis3dh_data* lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client);  

	switch (cmd)
	{
		case ST_IOCTL_APP_SET_RATE:
			
			if (copy_from_user(&rate, argp, sizeof(rate)))
			{
				return -EFAULT;
			}
			else
			{
				//nothing
			}
			
			break;
			
		default:
			break;
	}

	switch (cmd)
	{
		case ST_IOCTL_START:
			
        	mutex_lock(&(lis3dh->operation_mutex) );
        	stprintkd("to perform 'ST_IOCTL_START', former 'start_count' is %d.", lis3dh->start_count);
        	(lis3dh->start_count)++;
			
        	if ( 1 == lis3dh->start_count )
			{
            	atomic_set(&(lis3dh->data_ready), 0);
            	if ( (liRet = lis3dh_start(client, LIS3DH_RATE_12P5) ) < 0 ) 
				{
                	mutex_unlock(&(lis3dh->operation_mutex) );
                	return liRet;
            	}
				else
				{
					//nothing
				}
        	}
			else
			{
				//nothing
			}
        	mutex_unlock(&(lis3dh->operation_mutex) );
        	stprintkd("finish 'ST_IOCTL_START', ret = %d.", liRet);
        	return 0;

		case ST_IOCTL_CLOSE:
			
        	mutex_lock(&(lis3dh->operation_mutex) );
        	stprintkd("to perform 'ST_IOCTL_CLOSE', former 'start_count' is %d, PID : %d", lis3dh->start_count, get_current()->pid);
        	if ( 0 == (--(lis3dh->start_count) ) )
			{
            	atomic_set(&(lis3dh->data_ready), 0);
            	if ( (liRet = lis3dh_close(client) ) < 0 ) 
				{
                	mutex_unlock(&(lis3dh->operation_mutex) );
                	return liRet;
            	}
				else
				{
					//nothing
				}
        	}
        	mutex_unlock(&(lis3dh->operation_mutex) );
        	return 0;

		case ST_IOCTL_APP_SET_RATE:
			
			liRet = lis3dh_reset_rate(client, rate);
			if (liRet< 0)
			{
				return liRet;
			}
			else
			{
				//nothing
			}
			
			break;
			
		case ST_IOCTL_GETDATA:
			if ( (liRet = lis3dh_get_cached_data(client, &sense_data) ) < 0 )
			{
            	printk("failed to get cached sense data, ret = %d.", liRet);
				return liRet;
			}
			else
			{
				//nothing
			}
			break;
			
		default:
			return -ENOTTY;
	}

	switch (cmd)
	{
		case ST_IOCTL_GETDATA:
        	if ( copy_to_user(argp, &sense_data, sizeof(sense_data) ) )
			{
            	printk("failed to copy sense data to user space.");
				return -EFAULT;
        	}
			else
			{
				//npthing
			}
			break;
			
		default:
			break;
	}
	return 0;
}
示例#11
0
static void lis3dh_suspend(struct early_suspend *h)
{
	struct i2c_client *client = container_of(lis3dh_device.parent, struct i2c_client, dev);
	struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client);
	lis3dh_close(client);
}
示例#12
0
/**get the gsensor data. */
static int lis3dh_get_data(struct i2c_client *client)
{
	int liResult;
	int x,y,z;
	char acc_data[6];

	struct lis3dh_axis axis;
    struct lis3dh_data* lis3dh = i2c_get_clientdata(client);
    struct gsensor_platform_data *pdata = pdata = client->dev.platform_data;
	
	/* x,y,z hardware data */
	do {
		
        memset(acc_data, 0, 6);
        acc_data[0] = (I2C_AUTO_INCREMENT | AXISDATA_REG);
		
		liResult = lis3dh_rx_data(client, &acc_data[0], 6);
		if (liResult < 0)
		{
            return liResult;
        }
		else
		{
			//nothing
		}
    } while (0);
	
	stprintkd("0x%02x 0x%02x 0x%02x \n",acc_data[1],acc_data[3],acc_data[5]);
	
	x = lis3dh_convert_to_int(acc_data[1],acc_data[0]);
	y = lis3dh_convert_to_int(acc_data[3],acc_data[2]);
	z = lis3dh_convert_to_int(acc_data[5],acc_data[4]);

	axis.x = x;
	axis.y = z;
	axis.z = y;

	if (pdata->swap_xyz)
	{
		axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
		axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
		axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
	}
	else 
	{
		axis.x = x;
		axis.y = y;
		axis.z = z;
	}

	if(pdata->swap_xy)
	{
		axis.x = -axis.x;
		swap(axis.x,axis.y);		
	}
	
	stprintkd( "%s: GetData axis = %d  %d  %d-------\n",__func__, axis.x, axis.y, axis.z); 

    lis3dh_report_value(client, &axis);

    /* Caching data mutually exclusive.*/
    mutex_lock(&(lis3dh->sense_data_mutex) );
    lis3dh->sense_data = axis;
    mutex_unlock(&(lis3dh->sense_data_mutex) );

	/* set data_ready */
    atomic_set(&(lis3dh->data_ready), 1);
	/* wakeup the data_ready,the first of wait queue */
	wake_up(&(lis3dh->data_ready_wq) );

	return 0;
}
示例#13
0
static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
{
	struct rtc8564_data *data = i2c_get_clientdata(client);
	return (data->ctrl & 0xff00) >> 8;
}
示例#14
0
static int rtc8564_detach(struct i2c_client *client)
{
	i2c_detach_client(client);
	kfree(i2c_get_clientdata(client));
	return 0;
}
示例#15
0
static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{
    snd_soc_unregister_codec(&client->dev);
    kfree(i2c_get_clientdata(client));
    return 0;
}
示例#16
0
static int wis_tw2804_command(struct i2c_client *client,
				unsigned int cmd, void *arg)
{
	struct wis_tw2804 *dec = i2c_get_clientdata(client);

	if (cmd == DECODER_SET_CHANNEL) {
		int *input = arg;

		if (*input < 0 || *input > 3) {
			printk(KERN_ERR "wis-tw2804: channel %d is not "
					"between 0 and 3!\n", *input);
			return 0;
		}
		dec->channel = *input;
		printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
				"channel %d\n", dec->channel);
		if (dec->channel == 0 &&
				write_regs(client, global_registers, 0) < 0)
		{
			printk(KERN_ERR "wis-tw2804: error initializing "
					"TW2804 global registers\n");
			return 0;
		}
		if (write_regs(client, channel_registers, dec->channel) < 0)
		{
			printk(KERN_ERR "wis-tw2804: error initializing "
					"TW2804 channel %d\n", dec->channel);
			return 0;
		}
		return 0;
	}

	if (dec->channel < 0) {
		printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
				"channel number is set\n", cmd);
		return 0;
	}

	switch (cmd) {
	case DECODER_SET_NORM:
	{
		int *input = arg;
		u8 regs[] = {
			0x01, *input == VIDEO_MODE_NTSC ? 0xc4 : 0x84,
			0x09, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
			0x0a, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
			0x0b, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
			0x0c, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
			0x0d, *input == VIDEO_MODE_NTSC ? 0x40 : 0x4a,
			0x16, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
			0x17, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
			0x20, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
			0x21, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
			0xff,	0xff,
		};
		write_regs(client, regs, dec->channel);
		dec->norm = *input;
		break;
	}
	case VIDIOC_QUERYCTRL:
	{
		struct v4l2_queryctrl *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 255;
			ctrl->step = 1;
			ctrl->default_value = 128;
			ctrl->flags = 0;
			break;
		case V4L2_CID_CONTRAST:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 255;
			ctrl->step = 1;
			ctrl->default_value = 128;
			ctrl->flags = 0;
			break;
		case V4L2_CID_SATURATION:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 255;
			ctrl->step = 1;
			ctrl->default_value = 128;
			ctrl->flags = 0;
			break;
		case V4L2_CID_HUE:
			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
			ctrl->minimum = 0;
			ctrl->maximum = 255;
			ctrl->step = 1;
			ctrl->default_value = 128;
			ctrl->flags = 0;
			break;
		}
		break;
	}
	case VIDIOC_S_CTRL:
	{
		struct v4l2_control *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			if (ctrl->value > 255)
				dec->brightness = 255;
			else if (ctrl->value < 0)
				dec->brightness = 0;
			else
				dec->brightness = ctrl->value;
			write_reg(client, 0x12, dec->brightness, dec->channel);
			break;
		case V4L2_CID_CONTRAST:
			if (ctrl->value > 255)
				dec->contrast = 255;
			else if (ctrl->value < 0)
				dec->contrast = 0;
			else
				dec->contrast = ctrl->value;
			write_reg(client, 0x11, dec->contrast, dec->channel);
			break;
		case V4L2_CID_SATURATION:
			if (ctrl->value > 255)
				dec->saturation = 255;
			else if (ctrl->value < 0)
				dec->saturation = 0;
			else
				dec->saturation = ctrl->value;
			write_reg(client, 0x10, dec->saturation, dec->channel);
			break;
		case V4L2_CID_HUE:
			if (ctrl->value > 255)
				dec->hue = 255;
			else if (ctrl->value < 0)
				dec->hue = 0;
			else
				dec->hue = ctrl->value;
			write_reg(client, 0x0f, dec->hue, dec->channel);
			break;
		}
		break;
	}
	case VIDIOC_G_CTRL:
	{
		struct v4l2_control *ctrl = arg;

		switch (ctrl->id) {
		case V4L2_CID_BRIGHTNESS:
			ctrl->value = dec->brightness;
			break;
		case V4L2_CID_CONTRAST:
			ctrl->value = dec->contrast;
			break;
		case V4L2_CID_SATURATION:
			ctrl->value = dec->saturation;
			break;
		case V4L2_CID_HUE:
			ctrl->value = dec->hue;
			break;
		}
		break;
	}
	default:
		break;
	}
	return 0;
}
示例#17
0
static int __devexit sii9244C_remove(struct i2c_client *client)
{
	struct sii9244_state *state = i2c_get_clientdata(client);
	kfree(state);
	return 0;
}
示例#18
0
/*  Flash period = period * 0.128 + 0.256
	exception  0 = 0.128s
	please refer to data sheet for detail */
void ktd2026_set_period(int period)
{
	struct ktd2026_data *data = i2c_get_clientdata(b_client);

	data->shadow_reg[KTD2026_REG_FLASH_PERIOD] = period;
}
示例#19
0
文件: vpx3220.c 项目: ena30/snake-os
static int
vpx3220_command (struct i2c_client *client,
		 unsigned int       cmd,
		 void              *arg)
{
	struct vpx3220 *decoder = i2c_get_clientdata(client);

	switch (cmd) {
	case 0:
	{
		vpx3220_write_block(client, init_common,
				    sizeof(init_common));
		vpx3220_write_fp_block(client, init_fp,
				       sizeof(init_fp) >> 1);
		switch (decoder->norm) {
			
		case VIDEO_MODE_NTSC:
			vpx3220_write_fp_block(client, init_ntsc,
					       sizeof(init_ntsc) >> 1);
			break;

		case VIDEO_MODE_PAL:
			vpx3220_write_fp_block(client, init_pal,
				       	       sizeof(init_pal) >> 1);
			break;
		case VIDEO_MODE_SECAM:
			vpx3220_write_fp_block(client, init_secam,
					       sizeof(init_secam) >> 1);
			break;
		default:
			vpx3220_write_fp_block(client, init_pal,
				       	       sizeof(init_pal) >> 1);
			break;
		}
	}		
		break;

	case DECODER_DUMP:
	{
		vpx3220_dump_i2c(client);
	}
		break;

	case DECODER_GET_CAPABILITIES:
	{
		struct video_decoder_capability *cap = arg;

		dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
			I2C_NAME(client));

		cap->flags = VIDEO_DECODER_PAL |
			     VIDEO_DECODER_NTSC |
			     VIDEO_DECODER_SECAM |
			     VIDEO_DECODER_AUTO |
			     VIDEO_DECODER_CCIR;
		cap->inputs = 3;
		cap->outputs = 1;
	}
		break;

	case DECODER_GET_STATUS:
	{
		int res = 0, status;

		dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
			I2C_NAME(client));

		status = vpx3220_fp_read(client, 0x0f3);

		dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
			status);

		if (status < 0)
			return status;

		if ((status & 0x20) == 0) {
			res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;

			switch (status & 0x18) {

			case 0x00:
			case 0x10:
			case 0x14:
			case 0x18:
				res |= DECODER_STATUS_PAL;
				break;

			case 0x08:
				res |= DECODER_STATUS_SECAM;
				break;

			case 0x04:
			case 0x0c:
			case 0x1c:
				res |= DECODER_STATUS_NTSC;
				break;
			}
		}

		*(int *) arg = res;
	}
		break;

	case DECODER_SET_NORM:
	{
		int *iarg = arg, data;
		int temp_input;

		/* Here we back up the input selection because it gets
		   overwritten when we fill the registers with the
                   choosen video norm */
		temp_input = vpx3220_fp_read(client, 0xf2);

		dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
			I2C_NAME(client), *iarg);
		switch (*iarg) {

		case VIDEO_MODE_NTSC:
			vpx3220_write_fp_block(client, init_ntsc,
					       sizeof(init_ntsc) >> 1);
			dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
				I2C_NAME(client));
			break;

		case VIDEO_MODE_PAL:
			vpx3220_write_fp_block(client, init_pal,
					       sizeof(init_pal) >> 1);
			dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
				I2C_NAME(client));
			break;

		case VIDEO_MODE_SECAM:
			vpx3220_write_fp_block(client, init_secam,
					       sizeof(init_secam) >> 1);
			dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
				I2C_NAME(client));
			break;

		case VIDEO_MODE_AUTO:
			/* FIXME This is only preliminary support */
			data = vpx3220_fp_read(client, 0xf2) & 0x20;
			vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
			dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
				I2C_NAME(client));
			break;

		default:
			return -EINVAL;

		}
		decoder->norm = *iarg;

		/* And here we set the backed up video input again */
		vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
		udelay(10);
	}
		break;

	case DECODER_SET_INPUT:
	{
		int *iarg = arg, data;

		/* RJ:  *iarg = 0: ST8 (PCTV) input
		 *iarg = 1: COMPOSITE  input
		 *iarg = 2: SVHS       input  */

		const int input[3][2] = {
			{0x0c, 0},
			{0x0d, 0},
			{0x0e, 1}
		};

		if (*iarg < 0 || *iarg > 2)
			return -EINVAL;

		dprintk(1, KERN_INFO "%s: input switched to %s\n",
			I2C_NAME(client), inputs[*iarg]);

		vpx3220_write(client, 0x33, input[*iarg][0]);

		data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
		if (data < 0)
			return data;
		/* 0x0010 is required to latch the setting */
		vpx3220_fp_write(client, 0xf2,
				 data | (input[*iarg][1] << 5) | 0x0010);

		udelay(10);
	}
		break;

	case DECODER_SET_OUTPUT:
	{
		int *iarg = arg;

		/* not much choice of outputs */
		if (*iarg != 0) {
			return -EINVAL;
		}
	}
		break;

	case DECODER_ENABLE_OUTPUT:
	{
		int *iarg = arg;

		dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
			I2C_NAME(client), *iarg);

		vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
	}
		break;

	case DECODER_SET_PICTURE:
	{
		struct video_picture *pic = arg;

		if (decoder->bright != pic->brightness) {
			/* We want -128 to 128 we get 0-65535 */
			decoder->bright = pic->brightness;
			vpx3220_write(client, 0xe6,
				      (decoder->bright - 32768) >> 8);
		}
		if (decoder->contrast != pic->contrast) {
			/* We want 0 to 64 we get 0-65535 */
			/* Bit 7 and 8 is for noise shaping */
			decoder->contrast = pic->contrast;
			vpx3220_write(client, 0xe7,
				      (decoder->contrast >> 10) + 192);
		}
		if (decoder->sat != pic->colour) {
			/* We want 0 to 4096 we get 0-65535 */
			decoder->sat = pic->colour;
			vpx3220_fp_write(client, 0xa0,
					 decoder->sat >> 4);
		}
示例#20
0
/* MAX duty = 0xFF (99.6%) , min duty = 0x0 (0%) , 0.4% scale */
void ktd2026_set_pwm_duty(enum ktd2026_pwm pwm, int duty)
{
	struct ktd2026_data *data = i2c_get_clientdata(b_client);
	data->shadow_reg[KTD2026_REG_PWM1_TIMER + pwm] = duty;
}
static inline struct regulator_dev* rt5746_regulator_register(
	struct regulator_desc *regulator_desc, struct device *dev,
	struct regulator_init_data *init_data, void *driver_data)
{
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0))
    struct regulator_config config = {
        .dev = dev,
        .init_data = init_data,
        .driver_data = driver_data,
	.of_node = dev->of_node,
    };
    return regulator_register(&regulator_desc, &config);
#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(3,0,0))
    return regulator_register(regulator_desc,dev,init_data,
		driver_data,dev->of_node);
#else
    return regulator_register(regulator_desc,dev,init_data,driver_data);
#endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0)) */
}

static irqreturn_t rt5746_irq_handler(int irqno, void *param)
{
	struct rt5746_regulator_info *ri = param;
	int regval;
	int i;

	if (ri->suspend)
	{
		schedule_delayed_work(&ri->irq_dwork, msecs_to_jiffies(50));
		goto fin_intr;
	}

	regval = rt5746_reg_read(ri->i2c, RT5746_REG_INTACK);
	if (regval<0)
		dev_err(ri->dev, "read irq event io fail\n");
	else {
		if (regval == 0)
			goto fin_intr;
		regval &= (~rt5746_init_regval[0]);
		for (i=0; i<RT5746_IRQ_MAX; i++) {
			if (regval&(1<<i)) {
				switch (i) {
				case RT5746_IRQ_PGOOD:
					dev_err(ri->dev, "pgood event occur\n");
					break;
				case RT5746_IRQ_IDCDC:
					dev_err(ri->dev, "dcdc over current\n");
					break;
				case RT5746_IRQ_UVLO:
					dev_err(ri->dev, "uvlo event occur\n");
					break;
				case RT5746_IRQ_TPREW:
					dev_info(ri->dev, "thermal pre-warning\n");
					break;
				case RT5746_IRQ_TWARN:
					dev_warn(ri->dev, "thermal warning\n");
					break;
				case RT5746_IRQ_TSD:
					dev_err(ri->dev, "thermal shutdown\n");
					break;
				default:
					dev_err(ri->dev, "unrecognized event\n");
					break;
				}
			}
		}
	}
fin_intr:
	return IRQ_HANDLED;
}

static void rt5746_irq_dwork_func(struct work_struct *work)
{
	struct rt5746_regulator_info *ri = container_of(work,
		struct rt5746_regulator_info, irq_dwork.work);
	rt5746_irq_handler(0, ri);
}

static void rt5746_interrupt_init(struct rt5746_regulator_info *ri)
{
	struct rt5746_platform_data *pdata = ri->dev->platform_data;
	int rc = (int)0, irq_no = (int)0;
	if (gpio_is_valid(pdata->irq_gpio)) {
		rc = gpio_request(pdata->irq_gpio, "rt5746_irq_gpio");
		if (rc<0) {
			dev_err(ri->dev, "gpio request failed\n");
			return;
		}
		gpio_direction_input(pdata->irq_gpio);
		irq_no = gpio_to_irq(pdata->irq_gpio);
		if (irq_no<0) {
			dev_err(ri->dev, "gpio to irq fail\n");
			gpio_free(pdata->irq_gpio);
			return;
		}
		if (devm_request_threaded_irq(ri->dev, irq_no, NULL,
			rt5746_irq_handler,
			IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND|IRQF_DISABLED,
			"rt5746_irq", ri)) {
			dev_err(ri->dev, "request irq fail\n");
			gpio_free(pdata->irq_gpio);
			return;
		}
		enable_irq_wake(irq_no);
		schedule_delayed_work(&ri->irq_dwork, msecs_to_jiffies(100));
	}
	else
		dev_info(ri->dev, "gpio is not valid\n");
}

static void rt_parse_dt(struct device *dev)
{
	#ifdef CONFIG_OF
	struct regulator_init_data *init_data = NULL;
	struct rt5746_platform_data *pdata = dev->platform_data;
	struct device_node *np = dev->of_node;
	int rc;
	u32 tmp;
	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
	init_data = of_get_regulator_init_data(dev, dev->of_node);
	#else
	init_data = of_get_regulator_init_data(dev);
	#endif /* #if (LINUX_KERNEL_VERSION >= KERNEL_VERSION(3,3,0)) */

	pdata->regulator = init_data;
	rc = of_property_read_u32(np, "rt,standby_uV", &tmp);
	if (rc<0)
		dev_info(dev, "no standby voltage setting, use ic default\n");
	else
		pdata->standby_uV = tmp;

	rc = of_property_read_u32(np, "rt,rampup_sel", &tmp);
	if (rc)
		dev_info(dev, "no rampup_sel property, use ic default value\n");
	else
	{
		if (tmp>RT5746_RAMPUP_MAX)
			tmp = RT5746_RAMPUP_MAX;
		pdata->rampup_sel = tmp;
	}

	rc = of_property_read_u32(np, "rt,rampdn_sel", &tmp);
	if (rc)
		dev_info(dev, "no rampdn_sel property, use ic default value\n");
	else
	{
		if (tmp>RT5746_RAMPDN_MAX)
			tmp = RT5746_RAMPDN_MAX;
		pdata->rampdn_sel = tmp;
	}
	rc = of_property_read_u32(np, "rt,ipeak_sel", &tmp);
	if (rc)
		dev_info(dev, "no ipeak_sel property, use ic default value\n");
	else {
		if (tmp>RT5746_IPEAK_MAX)
			tmp = RT5746_IPEAK_MAX;
		pdata->ipeak_sel = tmp;
	}
	rc = of_property_read_u32(np, "rt,tpwth_sel", &tmp);
	if (rc)
		dev_info(dev, "no tpwth_sel property, use ic default value\n");
	else {
		if (tmp>RT5746_TPWTH_MAX)
			tmp = RT5746_TPWTH_MAX;
		pdata->tpwth_sel = tmp;
	}
	if (of_property_read_bool(np, "rt,rearm_en"))
		pdata->rearm_en = 1;
	if (of_property_read_bool(np, "rt,discharge_en"))
		pdata->discharge_en = 1;
	pdata->irq_gpio = of_get_named_gpio(np, "rt,irq_gpio", 0);
	#endif /* #ifdef CONFIG_OF */
}

static int rt5746_regulator_probe(struct i2c_client *i2c,
	const struct i2c_device_id *id)
{
	struct rt5746_regulator_info *ri;
	struct rt5746_platform_data *pdata = i2c->dev.platform_data;
	struct regulator_dev *rdev;
	struct regulator_init_data *init_data;
	bool use_dt = i2c->dev.of_node;
	int val = 0;
	int ret = 0;

	ri = &rt5746_regulator_info;
	if (use_dt) {
		pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata) {
			ret = -ENOMEM;
			goto err_init;
		}
		i2c->dev.platform_data = pdata;
		rt_parse_dt(&i2c->dev);
	}
	else {
		if (!pdata) {
			ret = -EINVAL;
			goto err_init;
		}
	}

	init_data = pdata->regulator;
	if (!init_data) {
		dev_err(&i2c->dev, "no initializing data\n");
		ret = -EINVAL;
		goto err_init;
	}

	mutex_init(&ri->io_lock);
	INIT_DELAYED_WORK(&ri->irq_dwork, rt5746_irq_dwork_func);
	ri->i2c = i2c;
	ri->dev = &i2c->dev;
	i2c_set_clientdata(i2c, ri);
	//check ic communication & ic vendor id
	val = rt5746_reg_read(i2c, RT5746_REG_VID);
	if (val<0) {
		ret = -EIO;
		goto err_init;
	}
	else {
		dev_info(&i2c->dev, "vendor id = %02x\n", val);
		if (val!=RT5746_VEN_ID) {
			ret = -EINVAL;
			goto err_init;
		}
	}
	rt5746_parse_initconfig(pdata);
	rt5746_register_init(i2c);

	//interrupt gpio init
	if (pdata->irq_gpio<0)
		dev_info(&i2c->dev, "no interrupt irq specified\n");
	else
		rt5746_interrupt_init(ri);

	rdev = rt5746_regulator_register(&ri->desc, &i2c->dev,
				  init_data, ri);
	if (IS_ERR(rdev)) {
		dev_err(&i2c->dev, "failed to register regulator %s\n",
				ri->desc.name);
		return PTR_ERR(rdev);
	}
	ri->rdev = rdev;
	//set suspend voltage
	if (pdata->standby_uV>0)
		rt5746_set_suspend_voltage(rdev, pdata->standby_uV);
	rt_dbg_create_attrs(&i2c->dev);
	dev_info(&i2c->dev, "regulator successfully registered\n");
err_init:
	return ret;
}

static int rt5746_regulator_remove(struct i2c_client *i2c)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	regulator_unregister(ri->rdev);
	dev_info(&i2c->dev, "regulator driver removed\n");
	return 0;
}

static int rt5746_regulator_suspend(struct i2c_client *i2c, pm_message_t mesg)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	ri->suspend = 1;
	return 0;
}

static int rt5746_regulator_resume(struct i2c_client *i2c)
{
	struct rt5746_regulator_info *ri = i2c_get_clientdata(i2c);
	ri->suspend = 0;
	return 0;
}

static const struct of_device_id rt_match_table[] = {
	{ .compatible = "richtek,rt5746",},
	{},
};
static int __devinit sec_nfc_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
#else
static int sec_nfc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
#endif
	struct sec_nfc_info *info = NULL;
	//struct sec_nfc_platform_data *pdata;
	struct sec_nfc_platform_data *pdata = NULL;
	int ret = 0;
	int err;

	pr_info("%s: enter - sec-nfc probe start\n", __func__);

    // Check tamper
    if (check_custom_kernel() == 1)
    {
//        pr_info("%s: The kernel is tampered. Couldn't initialize NFC. \n", __func__);
//        return -EPERM;
    }

	if(dev) {
		pr_info("%s: alloc for platform data\n", __func__);
		pdata = kzalloc(sizeof(struct sec_nfc_platform_data), GFP_KERNEL);

		if (!pdata) {
			dev_err(dev, "No platform data\n");
			ret = -ENOMEM;
			goto err_pdata;
		}
	}
	else {
		pr_info("%s: failed alloc platform data\n", __func__);
	}

	err = sec_nfc_parse_dt(dev, pdata);

	ret = gpio_request(pdata->tvdd, "nfc_tvdd");
		if (ret) {
			dev_err(dev, "failed to get gpio tvdd\n");
			goto err_gpio_tvdd;
		}
	ret = gpio_tlmm_config (GPIO_CFG(41, GPIOMUX_FUNC_GPIO,
					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
					GPIO_CFG_ENABLE);
	if (ret) {
		dev_err(dev, "failed to configure GPIO_41. ret %d \n", ret);
	} else {

		if (poweroff_charging) {
			pr_info("%s: [poweroff_charging] Setting the GPIO_41 pin LOW\n",__func__);
			gpio_set_value(41, 0);
			sec_nfc_uart_suspend();
		} else {
			pr_info("%s: [Normal case] Setting the GPIO_41 pin HIGH \n",__func__);
			gpio_set_value(41, 1);
		}
			pr_info("%s: Set the GPIO_41 (%d) to HIGH. \n", __func__, pdata->tvdd);
	}

	pr_info("gpio assign success!\n");

	info = kzalloc(sizeof(struct sec_nfc_info), GFP_KERNEL);
	if (!info) {
		dev_err(dev, "failed to allocate memory for sec_nfc_info\n");
		ret = -ENOMEM;
		kfree(pdata);
		goto err_info_alloc;
	}
	info->dev = dev;
	info->pdata = pdata;
	info->state = SEC_NFC_ST_OFF;

	mutex_init(&info->mutex);

	dev_set_drvdata(dev, info);

	//pdata->cfg_gpio();

#ifdef	CONFIG_SEC_NFC_I2C
	info->buflen = SEC_NFC_MAX_BUFFER_SIZE;
	info->buf = kzalloc(SEC_NFC_MAX_BUFFER_SIZE, GFP_KERNEL);
	if (!info->buf) {
		dev_err(dev,
			"failed to allocate memory for sec_nfc_info->buf\n");
		ret = -ENOMEM;
		kfree(pdata);
		goto err_buf_alloc;
	}
	info->i2c_dev = client;
	info->read_irq = SEC_NFC_NONE;
	mutex_init(&info->read_mutex);
	init_waitqueue_head(&info->read_wait);
	i2c_set_clientdata(client, info);

	ret = request_threaded_irq(pdata->irq, NULL, sec_nfc_irq_thread_fn,
			IRQF_TRIGGER_RISING | IRQF_ONESHOT, SEC_NFC_DRIVER_NAME,
			info);
	if (ret < 0) {
		dev_err(dev, "failed to register IRQ handler\n");
		goto err_irq_req;
	}

#endif

	wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, "NFCWAKE");

	info->miscdev.minor = MISC_DYNAMIC_MINOR;
	info->miscdev.name = SEC_NFC_DRIVER_NAME;
	info->miscdev.fops = &sec_nfc_fops;
	info->miscdev.parent = dev;
	ret = misc_register(&info->miscdev);

	if (ret < 0) {
		dev_err(dev, "failed to register Device\n");
		goto err_dev_reg;
	}

	ret = gpio_request(pdata->ven, "nfc_ven");
	if (ret) {
		dev_err(dev, "failed to get gpio ven\n");
		goto err_gpio_ven;
	}

	ret = gpio_request(pdata->firm, "nfc_firm");
	if (ret) {
		dev_err(dev, "failed to get gpio firm\n");
		goto err_gpio_firm;
	}

	gpio_direction_output(pdata->ven, 0);
	gpio_direction_output(pdata->firm, 0);


	dev_dbg(dev, "%s: info: %p, pdata %p\n", __func__, info, pdata);

#ifdef BU80003GUL
/*	ret = i2c_add_driver(&bu80003gul_i2c_driver);
	if (ret) {
		dev_err(dev,"%s Failed to add the i2c driver for the EEPROM chip. ret:%d \n",__func__, ret);
		goto err_gpio_firm;
	}
*/
#endif /* BU80003GUL */

	pr_info("%s: exit - sec-nfc probe finish\n", __func__);

	return 0;
err_gpio_tvdd:
	gpio_free(pdata->tvdd);
err_gpio_firm:
	gpio_free(pdata->firm);
err_gpio_ven:
	gpio_free(pdata->ven);
err_dev_reg:
#ifdef	CONFIG_SEC_NFC_I2C
err_irq_req:
err_buf_alloc:
#endif
err_info_alloc:

	if (info != NULL) {
		if (info->pdata != NULL) {
			kfree(info->pdata);
		}
		wake_lock_destroy(&info->wake_lock);
	kfree(info);
	}
err_pdata:
	pr_info("%s: exit - sec-nfc probe finish with ERROR! - ret = 0x%X\n", __func__, ret);
	return ret;
}


static void sec_nfc_shutdown(struct platform_device *pdev)
{
	struct sec_nfc_info *info = dev_get_drvdata(&pdev->dev);
	struct sec_nfc_platform_data *pdata = info->pdata;

	if (pdata->tvdd)
		gpio_set_value(pdata->tvdd, 0);
}


#ifdef	CONFIG_SEC_NFC_I2C
static int __devexit sec_nfc_remove(struct i2c_client *client)
{
	struct sec_nfc_info *info = i2c_get_clientdata(client);
	struct sec_nfc_platform_data *pdata = client->dev.platform_data;
#else
static int sec_nfc_remove(struct platform_device *pdev)
{
	struct sec_nfc_info *info = dev_get_drvdata(&pdev->dev);
	struct sec_nfc_platform_data *pdata = pdev->dev.platform_data;
#endif
	if(info == NULL) {
		goto ERR_SEC_NFC_REMOVE_INFO;
	}
	dev_dbg(info->dev, "%s\n", __func__);

	misc_deregister(&info->miscdev);

	if (info->state != SEC_NFC_ST_OFF) {
		gpio_set_value(pdata->firm, 0);
		gpio_set_value(pdata->ven, 0);
	}
	if(info->pdata != NULL) {
		kfree(info->pdata);
	}
	kfree(info);
ERR_SEC_NFC_REMOVE_INFO:
	gpio_free(pdata->firm);
	gpio_free(pdata->ven);

#ifdef	CONFIG_SEC_NFC_I2C
	free_irq(pdata->irq, info);
#endif

	wake_lock_destroy(&info->wake_lock);

#ifdef BU80003GUL
	i2c_del_driver(&bu80003gul_i2c_driver);
	felica_epc_deregister(); /*Naveen : TODO*/
	class_destroy(eeprom_class);
#endif
	return 0;
}

#ifdef	CONFIG_SEC_NFC_I2C
static struct i2c_device_id sec_nfc_id_table[] = {
#else	/* CONFIG_SEC_NFC_I2C */
static struct platform_device_id sec_nfc_id_table[] = {
#endif
	{ SEC_NFC_DRIVER_NAME, 0 },
	{ }
};

static struct of_device_id nfc_match_table[] = {
	{ .compatible = SEC_NFC_DRIVER_NAME, },
	{},
};

#ifdef	CONFIG_SEC_NFC_I2C
MODULE_DEVICE_TABLE(i2c, sec_nfc_id_table);
static struct i2c_driver sec_nfc_driver = {
#else
MODULE_DEVICE_TABLE(platform, sec_nfc_id_table);
static struct platform_driver sec_nfc_driver = {
#endif
	.probe = sec_nfc_probe,
	.id_table = sec_nfc_id_table,
	.shutdown = sec_nfc_shutdown,
	.remove = sec_nfc_remove,
	.driver = {
		.name = SEC_NFC_DRIVER_NAME,
#ifdef CONFIG_PM
		.pm = &sec_nfc_pm_ops,
#endif
		.of_match_table = nfc_match_table,
	},
};

#ifdef	CONFIG_SEC_NFC_I2C
static int __init sec_nfc_init(void)
{
	return i2c_add_driver(&sec_nfc_driver);
}

static void __exit sec_nfc_exit(void)
{
	i2c_del_driver(&sec_nfc_driver);
}
示例#23
0
/** 在 底半部执行, 具体获取 g sensor 数据. */
static int mma8452_get_data(struct i2c_client *client)
{
    struct mma8452_data* mma8452 = i2c_get_clientdata(client);
	char buffer[6];
	int ret;
	int x,y,z;
    struct mma8452_axis axis;
    struct mma8452_platform_data *pdata = pdata = client->dev.platform_data;

    do {
        memset(buffer, 0, 3);
        buffer[0] = MMA8452_REG_X_OUT_MSB;
		//ret = mma8452_tx_data(client, &buffer[0], 1);
        ret = mma8452_rx_data(client, &buffer[0], 3);
        if (ret < 0)
            return ret;
    } while (0);

	mmaprintkd("0x%02x 0x%02x 0x%02x \n",buffer[0],buffer[1],buffer[2]);
	
	x = mma8452_convert_to_int(buffer[0]);
	y = mma8452_convert_to_int(buffer[1]);
	z = mma8452_convert_to_int(buffer[2]);

	if (pdata->swap_xyz) {
		axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
		axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;	
		axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
	}
	else {
		axis.x = x;
		axis.y = y;	
		axis.z = z;
	}

	if(pdata->swap_xy)
	{
             axis.x = -axis.x;
             swap(axis.x,axis.y); 
	}
	
    mmaprintkd( "%s: ------------------mma8452_GetData axis = %d  %d  %d--------------\n",
            __func__, axis.x, axis.y, axis.z); 
     
    //memcpy(sense_data, &axis, sizeof(axis));
    mma8452_report_value(client, &axis);
	//atomic_set(&data_ready, 0);
	//wake_up(&data_ready_wq);

    /* 互斥地缓存数据. */
    mutex_lock(&(mma8452->sense_data_mutex) );
    mma8452->sense_data = axis;
    mutex_unlock(&(mma8452->sense_data_mutex) );

    /* 置位 data_ready */
    atomic_set(&(mma8452->data_ready), 1);
    /* 唤醒 data_ready 等待队列头. */
	wake_up(&(mma8452->data_ready_wq) );

	return 0;
}
示例#24
0
static int __devinit adp8860_led_probe(struct i2c_client *client)
{
	struct adp8860_backlight_platform_data *pdata =
		client->dev.platform_data;
	struct adp8860_bl *data = i2c_get_clientdata(client);
	struct adp8860_led *led, *led_dat;
	struct led_info *cur_led;
	int ret, i;

	led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
	if (led == NULL) {
		dev_err(&client->dev, "failed to alloc memory\n");
		return -ENOMEM;
	}

	ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law);
	ret = adp8860_write(client, ADP8860_ISCT1,
			(pdata->led_on_time & 0x3) << 6);
	ret |= adp8860_write(client, ADP8860_ISCF,
			FADE_VAL(pdata->led_fade_in, pdata->led_fade_out));

	if (ret) {
		dev_err(&client->dev, "failed to write\n");
		goto err_free;
	}

	for (i = 0; i < pdata->num_leds; ++i) {
		cur_led = &pdata->leds[i];
		led_dat = &led[i];

		led_dat->id = cur_led->flags & ADP8860_FLAG_LED_MASK;

		if (led_dat->id > 7 || led_dat->id < 1) {
			dev_err(&client->dev, "Invalid LED ID %d\n",
				led_dat->id);
			goto err;
		}

		if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) {
			dev_err(&client->dev, "LED %d used by Backlight\n",
				led_dat->id);
			goto err;
		}

		led_dat->cdev.name = cur_led->name;
		led_dat->cdev.default_trigger = cur_led->default_trigger;
		led_dat->cdev.brightness_set = adp8860_led_set;
		led_dat->cdev.brightness = LED_OFF;
		led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT;
		led_dat->client = client;
		led_dat->new_brightness = LED_OFF;
		INIT_WORK(&led_dat->work, adp8860_led_work);

		ret = led_classdev_register(&client->dev, &led_dat->cdev);
		if (ret) {
			dev_err(&client->dev, "failed to register LED %d\n",
				led_dat->id);
			goto err;
		}

		ret = adp8860_led_setup(led_dat);
		if (ret) {
			dev_err(&client->dev, "failed to write\n");
			i++;
			goto err;
		}
	}

	data->led = led;

	return 0;

 err:
	for (i = i - 1; i >= 0; --i) {
		led_classdev_unregister(&led[i].cdev);
		cancel_work_sync(&led[i].work);
	}

 err_free:
	kfree(led);

	return ret;
}
示例#25
0
static int isl29018_chip_init(struct i2c_client *client)
{
	struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client));
	int status;
	int new_adc_bit;
	unsigned int new_range;

	memset(chip->reg_cache, 0, sizeof(chip->reg_cache));

	/* Code added per Intersil Application Note 1534:
	 *     When VDD sinks to approximately 1.8V or below, some of
	 * the part's registers may change their state. When VDD
	 * recovers to 2.25V (or greater), the part may thus be in an
	 * unknown mode of operation. The user can return the part to
	 * a known mode of operation either by (a) setting VDD = 0V for
	 * 1 second or more and then powering back up with a slew rate
	 * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX
	 * conversions, clear the test registers, and then rewrite all
	 * registers to the desired values.
	 * ...
	 * FOR ISL29011, ISL29018, ISL29021, ISL29023
	 * 1. Write 0x00 to register 0x08 (TEST)
	 * 2. Write 0x00 to register 0x00 (CMD1)
	 * 3. Rewrite all registers to the desired values
	 *
	 * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says
	 * the same thing EXCEPT the data sheet asks for a 1ms delay after
	 * writing the CMD1 register.
	 */
	status = isl29018_write_data(client, ISL29018_REG_TEST, 0,
				ISL29018_TEST_MASK, ISL29018_TEST_SHIFT);
	if (status < 0) {
		dev_err(&client->dev, "Failed to clear isl29018 TEST reg."
					"(%d)\n", status);
		return status;
	}

	/* See Intersil AN1534 comments above.
	 * "Operating Mode" (COMMAND1) register is reprogrammed when
	 * data is read from the device.
	 */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0,
				0xff, 0);
	if (status < 0) {
		dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg."
					"(%d)\n", status);
		return status;
	}

	msleep(1);	/* per data sheet, page 10 */

	/* set defaults */
	status = isl29018_set_range(client, chip->range, &new_range);
	if (status < 0) {
		dev_err(&client->dev, "Init of isl29018 fails\n");
		return status;
	}

	status = isl29018_set_resolution(client, chip->adc_bit,
						&new_adc_bit);

	return 0;
}
示例#26
0
static int smb136_charging(struct i2c_client *client)
{
	struct smb136_chip *chg = i2c_get_clientdata(client);
	u8 data = 0;
	int gpio = 0;

	dev_info(&client->dev, "%s : enable(%d), cable(%d)\n",
		__func__, chg->is_enable, chg->cable_type);

	if(chg->is_enable) {
		switch(chg->cable_type)
		{
		case CABLE_TYPE_AC:
			//1. HC mode
			data = 0x8c;

			smb136_i2c_write(chg->client, SMB_CommandA, data);
			udelay(10);

			// 2. Change USB5/1/HC Control from Pin to I2C
			// 2. EN pin control - active low
			smb136_i2c_write(chg->client, SMB_PinControl, 0x8);
			udelay(10);

			smb136_i2c_write(chg->client, SMB_CommandA, 0x8c);
			udelay(10);

			//3. Set charge current to 950mA, termination current to 150mA
			data = 0x94;

			smb136_i2c_write(chg->client, SMB_ChargeCurrent, data);
			udelay(10);
			break;
		case CABLE_TYPE_USB:
		default:
			// 1. USBIN 500mA mode
			data = 0x88;

			smb136_i2c_write(chg->client, SMB_CommandA, data);
			udelay(10);

			// 2. Change USB5/1/HC Control from Pin to I2C
			// 2. EN pin control - active low
			smb136_i2c_write(chg->client, SMB_PinControl, 0x8);
			udelay(10);

			smb136_i2c_write(chg->client, SMB_CommandA, 0x88);
			udelay(10);

			// 3. Set charge current to 500mA, termination current to 150mA
			data = 0x14;

			smb136_i2c_write(chg->client, SMB_ChargeCurrent, data);
			udelay(10);
			break;
		}

		// 3. Enable Automatic Input Current Limit to 1000mA (threshold 4.25V)
		data = 0x60;
		smb136_i2c_write(chg->client, SMB_InputCurrentLimit, data);
		udelay(10);

		//4. Automatic Recharge Disabed
		data = 0x8c;
		smb136_i2c_write(chg->client, SMB_ControlA, data);
		udelay(10);

		//5. Safty timer Disabled
		data = 0x28;
		smb136_i2c_write(chg->client, SMB_ControlB, data);
		udelay(10);

		//6. Disable USB D+/D- Detection
		data = 0x28;
		smb136_i2c_write(chg->client, SMB_OTGControl, data);
		udelay(10);

		//7. Set Output Polarity for STAT
		//7. Set float voltage to 4.2V
		data = 0x4a;
		smb136_i2c_write(chg->client, SMB_FloatVoltage, data);
		udelay(10);

		//8. Re-load Enable
		data = 0x4b;
		smb136_i2c_write(chg->client, SMB_SafetyTimer, data);
		udelay(10);
	}
	else {
		// do nothing...
	}

	/* CHG_EN pin control - active low */
	gpio = gpio_request(chg->pdata->gpio_chg_en, "CHG_EN");
	if (!gpio) {
		gpio_direction_output(chg->pdata->gpio_chg_en, !(chg->is_enable));
		dev_info(&client->dev,
		"gpio(CHG_EN)is %d\n", gpio_get_value(chg->pdata->gpio_chg_en));
		gpio_free(chg->pdata->gpio_chg_en);
	} else
		dev_err(&client->dev,
		"faile to request gpio(CHG_EN)\n");

	/* smb136_test_read(client); */

	return 0;
}
示例#27
0
int autodetect_stereo(struct i2c_client *client)
{
	struct msp_state *state = i2c_get_clientdata(client);
	int val;
	int rxsubchans = state->rxsubchans;
	int newnicam   = state->nicam_on;
	int update = 0;

	switch (state->mode) {
	case MSP_MODE_FM_TERRA:
		val = msp_read_dsp(client, 0x18);
		if (val > 32767)
			val -= 65536;
		v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
		if (val > 4096) {
			rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
		} else if (val < -4096) {
			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
		} else {
			rxsubchans = V4L2_TUNER_SUB_MONO;
		}
		newnicam = 0;
		break;
	case MSP_MODE_FM_NICAM1:
	case MSP_MODE_FM_NICAM2:
	case MSP_MODE_AM_NICAM:
		val = msp_read_dem(client, 0x23);
		v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n",
			val & 1, (val & 0x1e) >> 1);

		if (val & 1) {
			/* nicam synced */
			switch ((val & 0x1e) >> 1)  {
			case 0:
			case 8:
				rxsubchans = V4L2_TUNER_SUB_STEREO;
				break;
			case 1:
			case 9:
				rxsubchans = V4L2_TUNER_SUB_MONO
					| V4L2_TUNER_SUB_LANG1;
				break;
			case 2:
			case 10:
				rxsubchans = V4L2_TUNER_SUB_MONO
					| V4L2_TUNER_SUB_LANG1
					| V4L2_TUNER_SUB_LANG2;
				break;
			default:
				rxsubchans = V4L2_TUNER_SUB_MONO;
				break;
			}
			newnicam = 1;
		} else {
			newnicam = 0;
			rxsubchans = V4L2_TUNER_SUB_MONO;
		}
		break;
	case MSP_MODE_BTSC:
		val = msp_read_dem(client, 0x200);
		v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
			val,
			(val & 0x0002) ? "no"     : "yes",
			(val & 0x0004) ? "no"     : "yes",
			(val & 0x0040) ? "stereo" : "mono",
			(val & 0x0080) ? ", nicam 2nd mono" : "",
			(val & 0x0100) ? ", bilingual/SAP"  : "");
		rxsubchans = V4L2_TUNER_SUB_MONO;
		if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
		if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
		break;
	}
示例#28
0
static void SM5414_charger_function_control(
				struct i2c_client *client)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);
	union power_supply_propval value;
	u8 ctrl;
	u8 chg_en;

	if (charger->charging_current < 0) {
		dev_info(&client->dev,
			"%s : OTG is activated. Ignore command!\n", __func__);
		return;
	}

	if (charger->cable_type == POWER_SUPPLY_TYPE_BATTERY) {
		/* Disable Charger */
		dev_info(&client->dev,
			"%s : Disable Charger, Battery Supply!\n", __func__);
		// nCHG_EN is logic low so set 1 to disable charger
		charger->is_fullcharged = false;
		gpio_direction_output((charger->pdata->chg_gpio_en), 1);
		SM5414_set_toggle_charger(client, 0);
	} else {

		psy_do_property("sec-fuelgauge", get,
				POWER_SUPPLY_PROP_CAPACITY, value);
		if (value.intval > 0) {
			/* Suspend enable for register reset */
			ctrl = 0x44;
			SM5414_i2c_write(client, SM5414_CTRL, &ctrl);
			msleep(20);

			ctrl = 0x40;
			SM5414_i2c_write(client, SM5414_CTRL, &ctrl);
		}

		dev_info(&client->dev, "%s : float voltage (%dmV)\n",
			__func__, charger->pdata->chg_float_voltage);

		/* Set float voltage */
		SM5414_set_float_voltage_data(
			client, charger->pdata->chg_float_voltage);

		dev_info(&client->dev, "%s : topoff current (%dmA)\n",
			__func__, charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st);
		SM5414_set_topoff_current_limit_data(
			client, charger->pdata->charging_current[
				charger->cable_type].full_check_current_1st);

		SM5414_i2c_read(client, SM5414_CTRL, &chg_en);

		if (!(chg_en & CHARGE_EN)) {
			SM5414_set_input_current_limit_data(client, 100);
			// nCHG_EN is logic low so set 0 to enable charger
			gpio_direction_output((charger->pdata->chg_gpio_en), 0);
			SM5414_set_toggle_charger(client, 1);
			msleep(100);

			/* Input current limit */
			dev_info(&client->dev, "%s : input current (%dmA)\n",
				__func__, charger->pdata->charging_current
				[charger->cable_type].input_current_limit);

			SM5414_set_input_current_limit_data(
				client, charger->pdata->charging_current
				[charger->cable_type].input_current_limit);
		}

		/* Set fast charge current */
		dev_info(&client->dev, "%s : fast charging current (%dmA), siop_level=%d\n",
			__func__, charger->charging_current, charger->pdata->siop_level);
		SM5414_set_fast_charging_current_data(
			client, charger->charging_current);

		dev_info(&client->dev,
			"%s : Enable Charger!\n", __func__);
	}
}
示例#29
0
static ssize_t bma250_selftest_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long data;
	unsigned char clear_value = 0;
	int error;
	short value1 = 0;
	short value2 = 0;
	short diff = 0;
	unsigned long result = 0;
	struct i2c_client *client = to_i2c_client(dev);
	struct bma250_data *bma250 = i2c_get_clientdata(client);

	error = strict_strtoul(buf, 10, &data);
	if (error)
		return error;

	if (data != 1)
		return -EINVAL;
	/* set to 2 G range */
	if (bma250_set_range(bma250->bma250_client, BMA250_RANGE_2G) < 0)
		return -EINVAL;

	bma250_smbus_write_byte(bma250->bma250_client, 0x32, &clear_value);
	/* 1 for x-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 1);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_x(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_x(bma250->bma250_client, &value2);
	diff = value1-value2;

	printk(KERN_INFO "diff x is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);

	if (abs(diff) < 204)
		result |= 1;

	/* 2 for y-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 2);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_y(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_y(bma250->bma250_client, &value2);
	diff = value1-value2;
	printk(KERN_INFO "diff y is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);
	if (abs(diff) < 204)
		result |= 2;

	/* 3 for z-axis*/
	bma250_set_selftest_st(bma250->bma250_client, 3);
	/* positive direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 0);
	mdelay(10);
	bma250_read_accel_z(bma250->bma250_client, &value1);
	/* negative direction*/
	bma250_set_selftest_stn(bma250->bma250_client, 1);
	mdelay(10);
	bma250_read_accel_z(bma250->bma250_client, &value2);
	diff = value1 - value2;

	printk(KERN_INFO "diff z is %d, value1 is %d, value2 is %d\n",
			diff, value1, value2);
	if (abs(diff) < 102)
		result |= 4;

	atomic_set(&bma250->selftest_result, (unsigned int) result);

	printk(KERN_INFO "self test finished\n");


	return count;
}
示例#30
0
int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
{
	struct sensor_private_data *sensor =
	    (struct sensor_private_data *) i2c_get_clientdata(client);
	struct sensor_platform_data *pdata;
	int result = 0;
	int type = 0;
	dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		result = -ENODEV;
		goto out_no_free;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->adapter->dev,
			"Missing platform data for slave %s\n", devid->name);
		result = -EFAULT;
		goto out_no_free;
	}

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor) {
		result = -ENOMEM;
		goto out_no_free;
	}

	type= pdata->type;	
	
	if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL))
	{	
		dev_err(&client->adapter->dev, "sensor type is error %d\n", pdata->type);
		result = -EFAULT;
		goto out_no_free;	
	}
	
	i2c_set_clientdata(client, sensor);
	sensor->client = client;	
	sensor->pdata = pdata;	
	sensor->type = type;
	sensor->i2c_id = (struct i2c_device_id *)devid;

	if (pdata->init_platform_hw) {
		result = pdata->init_platform_hw();
		if (result < 0)
			goto out_free_memory;
	}

	memset(&(sensor->axis), 0, sizeof(struct sensor_axis) );
	atomic_set(&(sensor->data_ready), 0);
	init_waitqueue_head(&(sensor->data_ready_wq));
	mutex_init(&sensor->data_mutex);	
	mutex_init(&sensor->operation_mutex);	
	mutex_init(&sensor->sensor_mutex);
	mutex_init(&sensor->i2c_mutex);

	sensor->status_cur = SENSOR_OFF;
	sensor->axis.x = 0;
	sensor->axis.y = 0;
	sensor->axis.z = 0;
	
	result = sensor_chip_init(sensor->client);
	if(result < 0)
		goto out_free_memory;
	
	sensor->input_dev = input_allocate_device();
	if (!sensor->input_dev) {
		result = -ENOMEM;
		dev_err(&client->dev,
			"Failed to allocate input device %s\n", sensor->input_dev->name);
		goto out_free_memory;
	}	

	switch(type)
	{
		case SENSOR_TYPE_ACCEL:	
			sensor->input_dev->name = "gsensor";
			set_bit(EV_ABS, sensor->input_dev->evbit);
			/* x-axis acceleration */
			input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
			/* y-axis acceleration */
			input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
			/* z-axis acceleration */
			input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
			break;		
		case SENSOR_TYPE_COMPASS:	
			sensor->input_dev->name = "compass";		
			/* Setup input device */
			set_bit(EV_ABS, sensor->input_dev->evbit);
			/* yaw (0, 360) */
			input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0);
			/* pitch (-180, 180) */
			input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0);
			/* roll (-90, 90) */
			input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0);
			/* x-axis acceleration (720 x 8G) */
			input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0);
			/* y-axis acceleration (720 x 8G) */
			input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0);
			/* z-axis acceleration (720 x 8G) */
			input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0);
			/* status of magnetic sensor */
			input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0);
			/* status of acceleration sensor */
			input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0);
			/* x-axis of raw magnetic vector (-4096, 4095) */
			input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0);
			/* y-axis of raw magnetic vector (-4096, 4095) */
			input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0);
			/* z-axis of raw magnetic vector (-4096, 4095) */
			input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0);
			break;		
		case SENSOR_TYPE_GYROSCOPE:
			sensor->input_dev->name = "gyro";
			/* x-axis acceleration */
			input_set_capability(sensor->input_dev, EV_REL, REL_RX);
			input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0); 
			/* y-axis acceleration */	
			input_set_capability(sensor->input_dev, EV_REL, REL_RY);
			input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0); 
			/* z-axis acceleration */
			input_set_capability(sensor->input_dev, EV_REL, REL_RZ);
			input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0); 
			break;
		case SENSOR_TYPE_LIGHT:
			sensor->input_dev->name = "lightsensor-level";
			set_bit(EV_ABS, sensor->input_dev->evbit);
			input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0);			
			break;
		case SENSOR_TYPE_PROXIMITY:
			sensor->input_dev->name = "proximity";	
			set_bit(EV_ABS, sensor->input_dev->evbit);
			input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
			break;
		case SENSOR_TYPE_TEMPERATURE:				
			sensor->input_dev->name = "temperature";
			set_bit(EV_ABS, sensor->input_dev->evbit);		
			input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
			break;
		default:
			printk("%s:unknow sensor type=%d\n",__func__,type);
			break;

	}
	sensor->input_dev->dev.parent = &client->dev;

	result = input_register_device(sensor->input_dev);
	if (result) {
		dev_err(&client->dev,
			"Unable to register input device %s\n", sensor->input_dev->name);
		goto out_input_register_device_failed;
	}

	result = sensor_irq_init(sensor->client);
	if (result) {
		dev_err(&client->dev,
			"fail to init sensor irq,ret=%d\n",result);
		goto out_input_register_device_failed;
	}

	
	sensor->miscdev.parent = &client->dev;
	result = sensor_misc_device_register(sensor, type);
	if (result) {
		dev_err(&client->dev,
			"fail to register misc device %s\n", sensor->miscdev.name);
		goto out_misc_device_register_device_failed;
	}
	
	g_sensor[type] = sensor;

#ifdef CONFIG_HAS_EARLYSUSPEND
	if((sensor->ops->suspend) && (sensor->ops->resume))
	{
		sensor->early_suspend.suspend = sensor_suspend;
		sensor->early_suspend.resume = sensor_resume;
		sensor->early_suspend.level = 0x02;
		register_early_suspend(&sensor->early_suspend);
	}
#endif

	printk("%s:initialized ok,sensor name:%s,type:%d\n",__func__,sensor->ops->name,type);

	return result;
	
out_misc_device_register_device_failed:
	input_unregister_device(sensor->input_dev);	
out_input_register_device_failed:
	input_free_device(sensor->input_dev);	
out_free_memory:
	kfree(sensor);
out_no_free:
	dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);
	return result;

}