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; }
/* 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); } }
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; }
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; }
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; }
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, };
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; }
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); }
/* * 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"); }
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; }
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); }
/**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; }
static inline u8 _rtc8564_ctrl2(struct i2c_client *client) { struct rtc8564_data *data = i2c_get_clientdata(client); return (data->ctrl & 0xff00) >> 8; }
static int rtc8564_detach(struct i2c_client *client) { i2c_detach_client(client); kfree(i2c_get_clientdata(client)); return 0; }
static __devexit int ak4535_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); kfree(i2c_get_clientdata(client)); return 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; }
static int __devexit sii9244C_remove(struct i2c_client *client) { struct sii9244_state *state = i2c_get_clientdata(client); kfree(state); return 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; }
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); }
/* 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(®ulator_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); }
/** 在 底半部执行, 具体获取 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; }
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; }
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; }
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; }
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; }
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__); } }
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; }
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; }