static int __devinit px3215_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct px3215_platform_data *pdata = client->dev.platform_data; struct px3215_data *data; struct device *proximity_device = NULL; int err = 0; int ret = 0; int error = 0; pr_info("[PX3215] probe\n"); this_client = client; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; data = kzalloc(sizeof(struct px3215_data), GFP_KERNEL); if (!data) return -ENOMEM; px3215_power.regulator_vdd = px3215_power.regulator_vio = NULL; px3215_power.regulator_vdd = regulator_get(&client->dev, "vdd_proxi"); if (IS_ERR(px3215_power.regulator_vdd)) { ret = PTR_ERR(px3215_power.regulator_vdd); pr_err("%s: failed to get vdd_proxi %d\n", __func__, ret); goto err_setup_regulator; } px3215_power.regulator_vio = regulator_get(&client->dev, "vio_proxi"); if (IS_ERR(px3215_power.regulator_vio)) { ret = PTR_ERR(px3215_power.regulator_vio); pr_err("%s: failed to get vio_proxi %d\n", __func__, ret); goto err_setup_regulator; } regulator_enable(px3215_power.regulator_vdd); mdelay(15); regulator_enable(px3215_power.regulator_vio); dev_set_name(&client->dev, client->name); data->gpio = pdata->ps_vout_gpio; data->client = client; data->irq = client->irq; i2c_set_clientdata(client, data); mutex_init(&data->lock); /* INT Settings */ data->irq = gpio_to_irq(data->gpio); if (data->irq < 0) { err = data->irq; pr_err("%s: Failed to convert GPIO %u to IRQ [errno=%d]", __func__, data->gpio, err); goto exit_kfree; } INIT_WORK(&data->work_ptime, px3215_work_func); /* initialize the PX3215C chip */ err = px3215_init_client(this_client); if (err) goto exit_kfree; err = px3215_input_init(data); if (err) goto exit_kfree; /* register sysfs hooks */ err = sysfs_create_group(&data->input->dev.kobj, &px3215_attr_group); if (err) goto exit_input; error = sensors_register(proximity_device, data, proximity_attrs, "proximity_sensor"); if (error < 0) { pr_err("%s: could not register gyro sensor device(%d).\n", __func__, error); goto exit_input; } /* IRQ Register */ err = request_threaded_irq(data->irq, NULL, px3215_irq, IRQF_TRIGGER_FALLING, "px3215", data); if (err) { pr_err("%s: request_irq failed for taos\n", __func__); goto exit_input; } /*irq_set_irq_wake(data->irq, 1);*/ disable_irq(data->irq); /*err = request_threaded_irq(client->irq, NULL, px3215_irq, IRQF_TRIGGER_FALLING, "px3215", data); if (err) { dev_err(&client->dev, "ret: %d, could not get IRQ %d\n",err,client->irq); goto exit_kfree; }*/ dev_info(&client->dev, "PX3215C driver version %s enabled\n", DRIVER_VERSION); return 0; exit_input: px3215_input_fini(data); exit_kfree: kfree(data); return err; err_setup_regulator: if (px3215_power.regulator_vdd) { regulator_disable(px3215_power.regulator_vdd); regulator_put(px3215_power.regulator_vdd); } if (px3215_power.regulator_vio) { regulator_disable(px3215_power.regulator_vio); regulator_put(px3215_power.regulator_vio); } return err; }
static int px3215_probe(struct i2c_client *client, const struct i2c_device_id *id) { printk("[PX3215] probe\n"); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct px3215_platform_data *pdata = client->dev.platform_data; struct px3215_data *data; struct device *proximity_device = NULL; int err = 0; int error = 0; this_client = client; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; data = kzalloc(sizeof(struct px3215_data), GFP_KERNEL); if (!data) { pr_err("%s: allocate data fail\n", __func__); err = -ENOMEM; goto exit_alloc_data; } dev_set_name(&client->dev, client->name); data->gpio = pdata->ps_vout_gpio; data->client = client; data->irq = client->irq; i2c_set_clientdata(client, data); mutex_init(&data->lock); /* initialize the PX3215C chip */ err = px3215_init_client(this_client); if (err) { pr_err("%s: chip init fail\n", __func__); goto exit_init_client; } err = px3215_input_init(data); if (err) { pr_err("%s: input device init fail\n", __func__); goto exit_input_device_init; } /* register sysfs hooks */ err = sysfs_create_group(&data->input->dev.kobj, &px3215_attr_group); if (err) { pr_err("%s: could not create sysfs group\n", __func__); goto exit_sysfs_create_group; } /* INT Settings */ if (pdata->hw_setup) pdata->hw_setup(); data->irq = gpio_to_irq(data->gpio); if (data->irq < 0) { err = data->irq; pr_err("%s: Failed to convert GPIO %u to IRQ [errno=%d]", __func__, data->gpio, err); goto exit_setup_irq; } err = request_threaded_irq(data->irq, NULL, px3215_irq, IRQF_TRIGGER_FALLING, "px3215", data); if (err) { pr_err("%s: request_irq failed for px3215\n", __func__); goto exit_setup_irq; } /*irq_set_irq_wake(data->irq, 1);*/ disable_irq(data->irq); /*initialize workqueue and timer for prox_avg calculation*/ data->wq_avg = create_singlethread_workqueue("prox_wq_avg"); if (!data->wq_avg) { err = -ENOMEM; pr_err("%s: could not create workqueue\n", __func__); goto err_create_avg_workqueue; } INIT_WORK(&data->work_prox_avg, prox_work_func_avg); data->prox_avg_enable = 0; hrtimer_init(&data->prox_avg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->prox_polling_time = ns_to_ktime(2000 * NSEC_PER_MSEC); data->prox_avg_timer.function = prox_timer_func; error = sensors_register(&proximity_device, data, proximity_attrs, "proximity_sensor"); if (error < 0) { pr_err("%s: could not register proximity sensor device(%d).\n", __func__, error); goto exit_sensors_register; } /* set initial proximity value as 1 */ input_report_abs(data->input, ABS_DISTANCE, 1); input_sync(data->input); dev_info(&client->dev, "PX3215C driver version %s enabled\n", DRIVER_VERSION); return 0; exit_sensors_register: destroy_workqueue(data->wq_avg); err_create_avg_workqueue: free_irq(data->irq, data); exit_setup_irq: sysfs_remove_group(&data->input->dev.kobj, &px3215_attr_group); exit_sysfs_create_group: px3215_input_fini(data); exit_input_device_init: exit_init_client: kfree(data); exit_alloc_data: return err; }