static int ltr558_devinit(void) { int error; int init_ps_gain; int init_als_gain; mdelay(PON_DELAY); // Enable PS to Gain1 at startup init_ps_gain = PS_RANGE1; //ps_gainrange = init_ps_gain; error = ltr558_ps_enable(init_ps_gain); if (error < 0) { printk("[ltr558] device init error!!!\n"); goto out; } // Enable ALS to Full Range at startup init_als_gain = ALS_RANGE2_64K; //als_gainrange = init_als_gain; error = ltr558_als_enable(init_als_gain); if (error < 0) { printk("[ltr558] device init error!!!\n"); goto out; } error = 0; printk("[ltr558] device init success!!!\n"); out: return error; }
static ssize_t store_prox_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ltr558_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; int err = 0; unsigned long lval; dev_vdbg(dev, "%s()\n", __func__); if (strict_strtoul(buf, 10, &lval)) return -EINVAL; if ((lval != 1) && (lval != 0)) { dev_err(dev, "illegal value %lu\n", lval); return -EINVAL; } mutex_lock(&chip->lock); if (lval == 1) { if (chip->supply[VDD]) { err = regulator_enable(chip->supply[VDD]); if (err) dev_err(dev, "vdd regulator enable failed\n"); } if (chip->supply[LED]) { err = regulator_enable(chip->supply[LED]); if (err) dev_err(dev, "led regulator enable failed\n"); } err = ltr558_ps_enable(client, PS_RANGE1); } else { err = ltr558_ps_disable(client); if (chip->supply[VDD]) { err = regulator_disable(chip->supply[VDD]); if (err) dev_err(dev, "vdd regulator disable failed\n"); } if (chip->supply[LED]) { err = regulator_disable(chip->supply[LED]); if (err) dev_err(dev, "led regulator disable failed\n"); } } if (err < 0) dev_err(dev, "Error in enabling proximity\n"); else chip->is_prox_enable = (lval) ? true : false; mutex_unlock(&chip->lock); return count; }
static int ltr558_suspend(struct i2c_client *client, pm_message_t mesg){ if (ltr558_data->p_enable){ disable_irq(ltr558_data->ltr558_irq); enable_irq_wake(ltr558_data->ltr558_irq); } if(tc4_get_call_flg() && (ltr558_ps_read() >= 0x214)) { ltr558_set_p_range(P_RANGE_2); ltr558_ps_enable(PS_GAINRANGE); } LTRDBG("ltr558 -----flag=%d--------%s\n",ltr558_data->p_enable, __func__); return 0; }
/******************************************* function:enable or disable the P-sensor parameter: @p_flag:the flag that we want to disblae or enable P-sensor PS_ENABLE: enable P-sensor PS_DISABLE: disable P-sensor return: return none zero means fail ********************************************/ static int ltr558_updata_ps_status(short p_flag){ int result = 0; if((PS_ENABLE == p_flag) && (PS_DISABLE == ltr558_data->p_enable)){ P_L_printk("eanble P-sensor\n"); result = ltr558_ps_enable(PS_GAINRANGE); if (0 == result){ ltr558_data->p_enable = PS_ENABLE; } }else if((PS_DISABLE == p_flag) && (PS_ENABLE == ltr558_data->p_enable)){ P_L_printk("disable P-sensor\n"); result = ltr558_ps_disable(); if(0 == result){ ltr558_data->p_enable = PS_DISABLE; } }else{ LTRDBG("P-sensor already %s\n", (p_flag) ? "enable" : "disable"); result = 0; } return result; }
static int ltr558_chip_init(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct ltr558_chip *chip = iio_priv(indio_dev); int error = 0; msleep(PON_DELAY); chip->is_prox_enable = 0; chip->prox_low_thres = 0; chip->prox_high_thres = 0x7FF; chip->prox_reading = 0; chip->als_low_thres = 0; chip->als_high_thres = 0xFFFF; chip->als_reading = 0; chip->is_als_enable = 0; chip->prox_persist = 0; chip->als_persist = 0; /* Enable PS to Gain1 at startup */ chip->ps_gainrange = PS_RANGE1; error = ltr558_ps_enable(client, chip->ps_gainrange); if (error < 0) goto out; /* Enable ALS to Full Range at startup */ chip->als_gainrange = ALS_RANGE2_64K; error = ltr558_als_enable(client, chip->als_gainrange); if (error < 0) goto out; out: return error; }
static int ltr558_probe(struct i2c_client *client, const struct i2c_device_id *id){ int ret = 0; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); /* Return 1 if adapter supports everything we need, 0 if not. */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE |I2C_FUNC_SMBUS_READ_BYTE_DATA)){ LTRERR(KERN_ALERT "%s: LTR-558ALS functionality check failed.\n", __func__); ret = -EIO; goto exit_check_functionality_failed; } /* data memory allocation */ ltr558_data = kzalloc(sizeof(struct ltr558_data), GFP_KERNEL); if (ltr558_data == NULL) { LTRERR(KERN_ALERT "%s: LTR-558ALS kzalloc failed.\n", __func__); ret = -ENOMEM; goto exit_alloc_data_failed; } ltr558_data->ltr558_irq = client->irq; //printk("%s: Irq number is == %d\n",client->irq); ltr558_data->p_enable = 0; ltr558_data->l_enable = 0; ltr558_data->ltr558_input = NULL; ltr558_data->client = client; INIT_WORK(&(ltr558_data->irq_workqueue),ltr558_schedwork); i2c_set_clientdata(client, ltr558_data); /*init device by send i2c command*/ ret = ltr558_devinit(); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS device init failed.\n", __func__); goto exit_device_init_failed; } /*init & register input dev*/ ltr558_data->ltr558_input = input_allocate_device(); if (ltr558_data->ltr558_input == NULL) { LTRERR(KERN_ALERT "%s: LTR-558ALS cllocate input device fail.\n", __func__); ret = -ENOMEM; goto exit_input_dev_alloc_failed; } ltr558_data->ltr558_input->name = "lightsensor"; set_bit(EV_ABS, ltr558_data->ltr558_input->evbit); input_set_abs_params(ltr558_data->ltr558_input, ABS_MISC, 0, 100000, 0, 0); input_set_abs_params(ltr558_data->ltr558_input, ABS_DISTANCE, 0, 128, 0, 0); ret = input_register_device(ltr558_data->ltr558_input); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS failed to register input device.\n", __func__); goto exit_input_register_device_failed; } /*register misc device*/ ret = misc_register(<r558_device); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS misc_register als failed.\n", __func__); goto exit_misc_device_register_failed; } /*init irq*/ ret = ltr558_gpio_irq(); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS gpio_irq failed.\n", __func__); goto exit_irq_request_failed; } #if 0 //add charles.hu just for test mdelay(600); ltr558_als_enable(ALS_RANGE2_64K); ltr558_ps_enable(PS_GAINRANGE); mdelay(600); P_L_printk("Ltr558 probe ok!!!\n"); //add end #endif return 0; exit_irq_request_failed: misc_deregister(<r558_device); exit_misc_device_register_failed: exit_input_register_device_failed: input_free_device(ltr558_data->ltr558_input); exit_input_dev_alloc_failed: exit_device_init_failed: kfree(ltr558_data); exit_alloc_data_failed: exit_check_functionality_failed: return ret; }
static int ltr558_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; int flag; int set_flag; void __user *argp = (void __user *)arg; switch (cmd) { case ECS_IOCTL_APP_SET_LFLAG: { LTR558_DBG("into set lflag!!!\n"); if (copy_from_user(&flag, argp, sizeof(flag))) { return -EFAULT; } atomic_set(&l_flag, flag); set_flag = atomic_read(&l_flag) ? 1 : 0; /*set bit 1 of reg 0 by set_flag */ if (set_flag) { ret = ltr558_als_enable(ltr_this_data,als_gainrange); if (ret < 0) { printk(KERN_ERR "%s:enable TLR558 als failed ,ret = %d\n", __func__,ret); } } else { LTR558_DBG("%s:disable light sensor\n", __func__); ret = ltr558_als_disable(ltr_this_data); if (ret < 0) { printk(KERN_ERR "%s:LTR set diable LFLAG is error(%d)!", __func__, ret); } } break; } case ECS_IOCTL_APP_GET_LFLAG: { flag = atomic_read(&l_flag); printk(KERN_ERR "%s:get light flag\n", __func__); if (copy_to_user(argp, &flag, sizeof(flag))) { return -EFAULT; } break; } case ECS_IOCTL_APP_SET_PFLAG: { if (copy_from_user(&flag, argp, sizeof(flag))) { return -EFAULT; } printk(KERN_ERR "%s:into ps_set \n", __func__); atomic_set(&p_flag, flag); set_flag = atomic_read(&p_flag) ? 1 : 0; if (set_flag) { ret = ltr558_ps_enable(ltr_this_data,ps_gainrange); if (ret < 0) { printk(KERN_ERR "%s:enable TLR558 ps failed . error(%d)!\n", __func__,ret); } } else { ret = ltr558_ps_disable(ltr_this_data); if (ret < 0) { printk(KERN_ERR "%s:LTR set ECS_IOCTL_APP_SET_PFLAG flag is error(%d)!", __func__, ret); } } break; } case ECS_IOCTL_APP_GET_PFLAG: { flag = atomic_read(&p_flag); printk(KERN_ERR "%s:get ps flag\n", __func__); if (copy_to_user(argp, &flag, sizeof(flag))) { return -EFAULT; } break; } case ECS_IOCTL_APP_SET_DELAY: { printk(KERN_ERR "%s:set delay", __func__); if (copy_from_user(&flag, argp, sizeof(flag))) { return -EFAULT; } if(flag) ltr_558_delay = flag; else ltr_558_delay = 20;/*20ms*/ break; } case ECS_IOCTL_APP_GET_DELAY: { flag = ltr_558_delay; if (copy_to_user(argp, &flag, sizeof(flag))) { return -EFAULT; } break; } default: { break; } } return ret; }