static int __devinit bh1721fvc_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct bh1721fvc_data *bh1721fvc; struct input_dev *input_dev; struct bh1721fvc_platform_data *pdata = client->dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); pr_info("%s: is started!\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -EIO; bh1721fvc = kzalloc(sizeof(*bh1721fvc), GFP_KERNEL); if (!bh1721fvc) { pr_err("%s, failed to alloc memory for module data\n", __func__); return -ENOMEM; } if (pdata != NULL) { bh1721fvc->reset = pdata->reset; if (!bh1721fvc->reset) { pr_err("%s: reset callback is null\n", __func__); err = -EIO; goto err_reset_null; } err = bh1721fvc->reset(); if (err) { pr_err("%s: Failed to reset\n", __func__); goto err_reset_failed; } } bh1721fvc->client = client; i2c_set_clientdata(client, bh1721fvc); mutex_init(&bh1721fvc->lock); bh1721fvc->state = POWER_DOWN; bh1721fvc->measure_mode = AUTO_MEASURE; err = bh1721fvc_test_luxvalue(bh1721fvc); if (err < 0) { pr_err("%s: No search bh1721fvc lightsensor!\n", __func__); goto err_test_lightsensor; } else { printk(KERN_ERR"Lux : %d\n", err); } hrtimer_init(&bh1721fvc->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); bh1721fvc->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); bh1721fvc->timer.function = bh1721fvc_timer_func; bh1721fvc->wq = alloc_workqueue("bh1721fvc_wq", WQ_UNBOUND | WQ_RESCUER, 1); if (!bh1721fvc->wq) { err = -ENOMEM; pr_err("%s: could not create workqueue\n", __func__); goto err_create_workqueue; } INIT_WORK(&bh1721fvc->work_light, bh1721fvc_work_func_light); input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); err = -ENOMEM; goto err_input_allocate_device_light; } input_set_drvdata(input_dev, bh1721fvc); input_dev->name = "light_sensor"; #if 0 input_set_capability(input_dev, EV_ABS, ABS_MISC); input_set_abs_params(input_dev, ABS_MISC, LUX_MIN_VALUE, LUX_MAX_VALUE, 0, 0); #else input_set_capability(input_dev, EV_REL, REL_MISC); #endif bh1721fvc_dbmsg("registering lightsensor-level input device\n"); err = input_register_device(input_dev); if (err < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_register_device_light; } bh1721fvc->input_dev = input_dev; err = sysfs_create_group(&input_dev->dev.kobj, &bh1721fvc_attribute_group); if (err) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } /* set sysfs for light sensor */ bh1721fvc->light_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(bh1721fvc->light_dev)) { pr_err("%s: could not create light_dev\n", __func__); goto err_light_device_create; } if (device_create_file(bh1721fvc->light_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_light_device_create_file1; } if (device_create_file(bh1721fvc->light_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_light_device_create_file2; } if (device_create_file(bh1721fvc->light_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_light_device_create_file3; } dev_set_drvdata(bh1721fvc->light_dev, bh1721fvc); pr_info("%s: success!\n", __func__); goto done; err_light_device_create_file3: device_remove_file(bh1721fvc->light_dev, &dev_attr_vendor); err_light_device_create_file2: device_remove_file(bh1721fvc->light_dev, &dev_attr_raw_data); err_light_device_create_file1: sensors_classdev_unregister(bh1721fvc->light_dev); err_light_device_create: sysfs_remove_group(&bh1721fvc->input_dev->dev.kobj, &bh1721fvc_attribute_group); err_sysfs_create_group_light: input_unregister_device(bh1721fvc->input_dev); err_input_register_device_light: err_input_allocate_device_light: destroy_workqueue(bh1721fvc->wq); err_create_workqueue: err_test_lightsensor: mutex_destroy(&bh1721fvc->lock); err_reset_failed: err_reset_null: kfree(bh1721fvc); done: return err; }
static int lsm330dlc_gyro_probe(struct i2c_client *client, const struct i2c_device_id *devid) { int ret; int err = 0; struct lsm330dlc_gyro_data *data; struct input_dev *input_dev; pr_info("%s, started", __func__); data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) { dev_err(&client->dev, "failed to allocate memory for module data\n"); err = -ENOMEM; goto exit; } data->client = client; data->drop_next_event = 0; /* read chip id */ ret = i2c_smbus_read_byte_data(client, WHO_AM_I); if (ret != DEVICE_ID) { if (ret < 0) { pr_err("%s: i2c for reading chip id failed\n", __func__); err = ret; } else { pr_err("%s : Device identification failed\n", __func__); err = -ENODEV; } goto err_read_reg; } mutex_init(&data->lock); atomic_set(&data->opened, 0); init_completion(&data->data_ready); /* allocate gyro input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); err = -ENOMEM; goto err_input_allocate_device; } data->input_dev = input_dev; input_set_drvdata(input_dev, data); input_dev->name = L3GD20_GYR_INPUT_NAME; /* X */ input_set_capability(input_dev, EV_REL, REL_RX); /* Y */ input_set_capability(input_dev, EV_REL, REL_RY); /* Z */ input_set_capability(input_dev, EV_REL, REL_RZ); err = input_register_device(input_dev); if (err < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(data->input_dev); goto err_input_register_device; } i2c_set_clientdata(client, data); dev_set_drvdata(&input_dev->dev, data); if (data->client->irq >= 0) { /* interrupt */ memcpy(&data->ctrl_regs, &default_ctrl_regs_fifo, sizeof(default_ctrl_regs_fifo)); data->interruptible = true; data->entries = 1; err = request_threaded_irq(data->client->irq, NULL, lsm330dlc_gyro_interrupt_thread\ , IRQF_TRIGGER_RISING | IRQF_ONESHOT,\ "lsm330dlc_gyro", data); if (err < 0) { pr_err("%s: can't allocate irq.\n", __func__); goto err_request_irq; } disable_irq(data->client->irq); } else { /* polling */ memcpy(&data->ctrl_regs, &default_ctrl_regs_bypass, sizeof(default_ctrl_regs_bypass)); data->ctrl_regs[2] = 0x00; /* disable interrupt */ /* hrtimer settings. we poll for gyro values using a timer. */ hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->polling_delay = ns_to_ktime(200 * NSEC_PER_MSEC); data->timer.function = lsm330dlc_gyro_timer_func; /* the timer just fires off a work queue request. We need a thread to read i2c (can be slow and blocking). */ data->lsm330dlc_gyro_wq \ = create_singlethread_workqueue("lsm330dlc_gyro_wq"); if (!data->lsm330dlc_gyro_wq) { err = -ENOMEM; pr_err("%s: could not create workqueue\n", __func__); goto err_create_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&data->work, lsm330dlc_gyro_work_func); } if (device_create_file(&input_dev->dev, &dev_attr_enable) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_enable.attr.name); goto err_device_create_file; } if (device_create_file(&input_dev->dev, &dev_attr_poll_delay) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_poll_delay.attr.name); goto err_device_create_file2; } /* create device node for lsm330dlc_gyro digital gyroscope */ data->dev = sensors_classdev_register("gyro_sensor"); if (IS_ERR(data->dev)) { pr_err("%s: Failed to create device(gyro)\n", __func__); err = PTR_ERR(data->dev); goto err_device_create; } if (device_create_file(data->dev, &dev_attr_power_on) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_power_on.attr.name); goto err_device_create_file3; } if (device_create_file(data->dev, &dev_attr_power_off) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_power_off.attr.name); goto err_device_create_file4; } if (device_create_file(data->dev, &dev_attr_temperature) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_temperature.attr.name); goto err_device_create_file5; } if (device_create_file(data->dev, &dev_attr_selftest) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_selftest.attr.name); goto err_device_create_file6; } if (device_create_file(data->dev, &dev_attr_selftest_dps) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_selftest_dps.attr.name); goto err_device_create_file7; } if (device_create_file(data->dev, &dev_attr_vendor) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_device_create_file8; } if (device_create_file(data->dev, &dev_attr_name) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_device_create_file9; } #ifdef DEBUG_REGISTER if (device_create_file(data->dev, &dev_attr_reg_data) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_reg_data.attr.name); goto err_device_create_file10; } #endif dev_set_drvdata(data->dev, data); pr_info("%s, successful", __func__); return 0; #ifdef DEBUG_REGISTER err_device_create_file10: device_remove_file(data->dev, &dev_attr_name); #endif err_device_create_file9: device_remove_file(data->dev, &dev_attr_vendor); err_device_create_file8: device_remove_file(data->dev, &dev_attr_selftest_dps); err_device_create_file7: device_remove_file(data->dev, &dev_attr_selftest); err_device_create_file6: device_remove_file(data->dev, &dev_attr_temperature); err_device_create_file5: device_remove_file(data->dev, &dev_attr_power_off); err_device_create_file4: device_remove_file(data->dev, &dev_attr_power_on); err_device_create_file3: sensors_classdev_unregister(data->dev); err_device_create: device_remove_file(&input_dev->dev, &dev_attr_poll_delay); err_device_create_file2: device_remove_file(&input_dev->dev, &dev_attr_enable); err_device_create_file: if (data->interruptible) free_irq(data->client->irq, data); else destroy_workqueue(data->lsm330dlc_gyro_wq); err_create_workqueue: err_request_irq: input_unregister_device(data->input_dev); err_input_register_device: err_input_allocate_device: mutex_destroy(&data->lock); err_read_reg: kfree(data); exit: return err; }
static int cm3323_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm3323_data *cm3323 = NULL; pr_info("%s is called.\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } cm3323 = kzalloc(sizeof(struct cm3323_data), GFP_KERNEL); if (!cm3323) { pr_err ("%s: failed to alloc memory for RGB sensor module data\n", __func__); return -ENOMEM; } cm3323->i2c_client = client; i2c_set_clientdata(client, cm3323); mutex_init(&cm3323->power_lock); mutex_init(&cm3323->read_lock); /* Check if the device is there or not. */ ret = cm3323_setup_reg(cm3323); if (ret < 0) { pr_err("%s: could not setup regs\n", __func__); goto err_setup_reg; } /* allocate lightsensor input_device */ cm3323->light_input_dev = input_allocate_device(); if (!cm3323->light_input_dev) { pr_err("%s: could not allocate light input device\n", __func__); goto err_input_allocate_device_light; } input_set_drvdata(cm3323->light_input_dev, cm3323); cm3323->light_input_dev->name = "light_sensor"; input_set_capability(cm3323->light_input_dev, EV_REL, REL_RED); input_set_capability(cm3323->light_input_dev, EV_REL, REL_GREEN); input_set_capability(cm3323->light_input_dev, EV_REL, REL_BLUE); input_set_capability(cm3323->light_input_dev, EV_REL, REL_WHITE); ret = input_register_device(cm3323->light_input_dev); if (ret < 0) { input_free_device(cm3323->light_input_dev); pr_err("%s: could not register input device\n", __func__); goto err_input_register_device_light; } ret = sysfs_create_group(&cm3323->light_input_dev->dev.kobj, &light_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm3323->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm3323->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); cm3323->light_timer.function = cm3323_light_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm3323->light_wq = create_singlethread_workqueue("cm3323_light_wq"); if (!cm3323->light_wq) { ret = -ENOMEM; pr_err("%s: could not create light workqueue\n", __func__); goto err_create_light_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm3323->work_light, cm3323_work_func_light); /* set sysfs for light sensor */ cm3323->light_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(cm3323->light_dev)) { pr_err("%s: could not create light_dev\n", __func__); goto err_light_device_create; } if (device_create_file(cm3323->light_dev, &dev_attr_lux) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lux.attr.name); goto err_light_device_create_file1; } if (device_create_file(cm3323->light_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_light_device_create_file2; } if (device_create_file(cm3323->light_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_light_device_create_file3; } if (device_create_file(cm3323->light_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_light_device_create_file4; } dev_set_drvdata(cm3323->light_dev, cm3323); pr_info("%s is success.\n", __func__); goto done; /* error, unwind it all */ err_light_device_create_file4: device_remove_file(cm3323->light_dev, &dev_attr_vendor); err_light_device_create_file3: device_remove_file(cm3323->light_dev, &dev_attr_raw_data); err_light_device_create_file2: device_remove_file(cm3323->light_dev, &dev_attr_lux); err_light_device_create_file1: sensors_classdev_unregister(cm3323->light_dev); err_light_device_create: destroy_workqueue(cm3323->light_wq); err_create_light_workqueue: sysfs_remove_group(&cm3323->light_input_dev->dev.kobj, &light_attribute_group); err_sysfs_create_group_light: input_unregister_device(cm3323->light_input_dev); err_input_register_device_light: err_input_allocate_device_light: err_setup_reg: mutex_destroy(&cm3323->read_lock); mutex_destroy(&cm3323->power_lock); kfree(cm3323); done: return ret; }
static int gp2a_opt_probe(struct platform_device *pdev) { struct gp2a_data *gp2a; struct gp2a_platform_data *pdata = pdev->dev.platform_data; u8 value = 0; int err = 0; gprintk("probe start!\n"); if (!pdata) { pr_err("%s: missing pdata!\n", __func__); return err; } if (!pdata->gp2a_led_on) { pr_err("%s: incomplete pdata!\n", __func__); return err; } /* gp2a power on */ pdata->gp2a_led_on(true); if (pdata->gp2a_get_threshold) { gp2a_update_threshold(is_gp2a030a() ? gp2a_original_image_030a : gp2a_original_image, pdata->gp2a_get_threshold(), false); } /* allocate driver_data */ gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!gp2a) { pr_err("kzalloc error\n"); return -ENOMEM; } proximity_enable = 0; proximity_sensor_detection = 0; proximity_avg_on = 0; gp2a->enabled = 0; gp2a->pdata = pdata; /* prox_timer settings. we poll for prox_avg values using a timer. */ hrtimer_init(&gp2a->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); gp2a->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC); gp2a->prox_timer.function = gp2a_prox_timer_func; gp2a->prox_wq = create_singlethread_workqueue("gp2a_prox_wq"); if (!gp2a->prox_wq) { err = -ENOMEM; pr_err("%s: could not create prox workqueue\n", __func__); goto err_create_prox_workqueue; } INIT_WORK(&gp2a->work_prox, gp2a_work_func_prox_avg); INIT_WORK(&gp2a->work, gp2a_work_func_prox); err = proximity_input_init(gp2a); if (err < 0) goto error_setup_reg; err = sysfs_create_group(&gp2a->input_dev->dev.kobj, &proximity_attribute_group); if (err < 0) goto err_sysfs_create_group_proximity; /* set platdata */ platform_set_drvdata(pdev, gp2a); /* wake lock init */ wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); /* init i2c */ opt_i2c_init(); if (opt_i2c_client == NULL) { pr_err("opt_probe failed : i2c_client is NULL\n"); goto err_no_device; } else printk(KERN_INFO "opt_i2c_client : (0x%p), address = %x\n", opt_i2c_client, opt_i2c_client->addr); /* GP2A Regs INIT SETTINGS and Check I2C communication */ value = 0x00; /* shutdown mode op[3]=0 */ err = opt_i2c_write((u8) (COMMAND1), &value); if (err < 0) { pr_err("%s failed : threre is no such device.\n", __func__); goto err_no_device; } /* Setup irq */ err = gp2a_setup_irq(gp2a); if (err) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } /* set sysfs for proximity sensor */ gp2a->proximity_dev = sensors_classdev_register("proximity_sensor"); if (IS_ERR(gp2a->proximity_dev)) { pr_err("%s: could not create proximity_dev\n", __func__); goto err_proximity_device_create; } if (device_create_file(gp2a->proximity_dev, &dev_attr_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_state.attr.name); goto err_proximity_device_create_file1; } if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_avg) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_avg.attr.name); goto err_proximity_device_create_file2; } if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_thresh) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_thresh.attr.name); goto err_proximity_device_create_file3; } if (device_create_file(gp2a->proximity_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_proximity_device_create_file4; } if (device_create_file(gp2a->proximity_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_proximity_device_create_file5; } if (device_create_file(gp2a->proximity_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_proximity_device_create_file6; } #ifdef CONFIG_SLP device_init_wakeup(gp2a->proximity_dev, true); #endif dev_set_drvdata(gp2a->proximity_dev, gp2a); device_init_wakeup(&pdev->dev, 1); gprintk("probe success!\n"); return 0; err_proximity_device_create_file6: device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data); err_proximity_device_create_file5: device_remove_file(gp2a->proximity_dev, &dev_attr_name); err_proximity_device_create_file4: device_remove_file(gp2a->proximity_dev, &dev_attr_vendor); err_proximity_device_create_file3: device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg); err_proximity_device_create_file2: device_remove_file(gp2a->proximity_dev, &dev_attr_state); err_proximity_device_create_file1: sensors_classdev_unregister(gp2a->proximity_dev); err_proximity_device_create: gpio_free(pdata->p_out); err_setup_irq: err_no_device: sysfs_remove_group(&gp2a->input_dev->dev.kobj, &proximity_attribute_group); wake_lock_destroy(&gp2a->prx_wake_lock); err_sysfs_create_group_proximity: input_unregister_device(gp2a->input_dev); error_setup_reg: destroy_workqueue(gp2a->prox_wq); err_create_prox_workqueue: kfree(gp2a); return err; }
static int cm3663_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct input_dev *input_dev; struct cm3663_data *cm3663; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } cm3663 = kzalloc(sizeof(struct cm3663_data), GFP_KERNEL); if (!cm3663) { pr_err("%s: failed to alloc memory for module data\n", __func__); return -ENOMEM; } cm3663->pdata = client->dev.platform_data; cm3663->i2c_client = client; i2c_set_clientdata(client, cm3663); /* wake lock init */ wake_lock_init(&cm3663->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); mutex_init(&cm3663->power_lock); /* setup initial registers */ ret = cm3663_setup_reg(cm3663); if (ret < 0) { pr_err("%s: could not setup regs\n", __func__); goto err_setup_reg; } ret = cm3663_setup_irq(cm3663); if (ret) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } /* allocate proximity input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); goto err_input_allocate_device_proximity; } cm3663->proximity_input_dev = input_dev; input_set_drvdata(input_dev, cm3663); input_dev->name = "proximity_sensor"; input_set_capability(input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_register_device_proximity; } ret = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm3663->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm3663->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); cm3663->light_timer.function = cm3663_light_timer_func; /* prox_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm3663->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm3663->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC); cm3663->prox_timer.function = cm3663_prox_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm3663->light_wq = create_singlethread_workqueue("cm3663_light_wq"); if (!cm3663->light_wq) { ret = -ENOMEM; pr_err("%s: could not create light workqueue\n", __func__); goto err_create_light_workqueue; } cm3663->prox_wq = create_singlethread_workqueue("cm3663_prox_wq"); if (!cm3663->prox_wq) { ret = -ENOMEM; pr_err("%s: could not create prox workqueue\n", __func__); goto err_create_prox_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm3663->work_light, cm3663_work_func_light); INIT_WORK(&cm3663->work_prox, cm3663_work_func_prox); /* allocate lightsensor-level input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); ret = -ENOMEM; goto err_input_allocate_device_light; } input_set_drvdata(input_dev, cm3663); input_dev->name = "light_sensor"; #if defined(CONFIG_MACH_S2PLUS) input_set_capability(input_dev, EV_REL, REL_MISC); #else input_set_capability(input_dev, EV_ABS, ABS_MISC); input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0); #endif ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_register_device_light; } cm3663->light_input_dev = input_dev; ret = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } #if defined(CONFIG_MACH_S2PLUS) /* set sysfs for proximity sensor */ cm3663->proximity_dev = sensors_classdev_register("proximity_sensor"); if (IS_ERR(cm3663->proximity_dev)) { pr_err("%s: could not create proximity_dev\n", __func__); goto err_proximity_classdev_create; } if (device_create_file(cm3663->proximity_dev, &dev_attr_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_state.attr.name); goto err_proximity_device_create_file1; } if (device_create_file(cm3663->proximity_dev, &dev_attr_prox_avg) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_avg.attr.name); goto err_proximity_device_create_file2; } dev_set_drvdata(cm3663->proximity_dev, cm3663); /* set sysfs for light sensor */ cm3663->switch_cmd_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(cm3663->switch_cmd_dev)) { pr_err("%s: could not create switch_cmd_dev\n", __func__); goto err_light_classdev_create; } if (device_create_file(cm3663->switch_cmd_dev, &dev_attr_lux) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lux.attr.name); goto err_light_device_create_file; } dev_set_drvdata(cm3663->switch_cmd_dev, cm3663); #else /* set sysfs for proximity sensor */ cm3663->proximity_class = class_create(THIS_MODULE, "proximity"); if (IS_ERR(cm3663->proximity_class)) { pr_err("%s: could not create proximity_class\n", __func__); goto err_proximity_class_create; } cm3663->proximity_dev = device_create(cm3663->proximity_class, NULL, 0, NULL, "proximity"); if (IS_ERR(cm3663->proximity_dev)) { pr_err("%s: could not create proximity_dev\n", __func__); goto err_proximity_device_create; } if (device_create_file(cm3663->proximity_dev, &dev_attr_proximity_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_proximity_state.attr.name); goto err_proximity_device_create_file1; } if (device_create_file(cm3663->proximity_dev, &dev_attr_proximity_avg) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_proximity_avg.attr.name); goto err_proximity_device_create_file2; } dev_set_drvdata(cm3663->proximity_dev, cm3663); /* set sysfs for light sensor */ cm3663->lightsensor_class = class_create(THIS_MODULE, "lightsensor"); if (IS_ERR(cm3663->lightsensor_class)) { pr_err("%s: could not create lightsensor_class\n", __func__); goto err_light_class_create; } cm3663->switch_cmd_dev = device_create(cm3663->lightsensor_class, NULL, 0, NULL, "switch_cmd"); if (IS_ERR(cm3663->switch_cmd_dev)) { pr_err("%s: could not create switch_cmd_dev\n", __func__); goto err_light_device_create; } if (device_create_file(cm3663->switch_cmd_dev, &dev_attr_lightsensor_file_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lightsensor_file_state.attr.name); goto err_light_device_create_file; } dev_set_drvdata(cm3663->switch_cmd_dev, cm3663); #endif /* set initial proximity value (far) */ input_report_abs(cm3663->proximity_input_dev, ABS_DISTANCE, 1); input_sync(cm3663->proximity_input_dev); goto done; /* error, unwind it all */ #if defined(CONFIG_MACH_S2PLUS) err_light_device_create_file: sensors_classdev_unregister(cm3663->switch_cmd_dev); err_light_classdev_create: device_remove_file(cm3663->proximity_dev, &dev_attr_prox_avg); err_proximity_device_create_file2: device_remove_file(cm3663->proximity_dev, &dev_attr_state); err_proximity_device_create_file1: sensors_classdev_unregister(cm3663->proximity_dev); err_proximity_classdev_create: #else err_light_device_create_file: device_destroy(cm3663->lightsensor_class, 0); err_light_device_create: class_destroy(cm3663->lightsensor_class); err_light_class_create: device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_avg); err_proximity_device_create_file2: device_remove_file(cm3663->proximity_dev, &dev_attr_proximity_state); err_proximity_device_create_file1: device_destroy(cm3663->proximity_class, 0); err_proximity_device_create: class_destroy(cm3663->proximity_class); err_proximity_class_create: #endif sysfs_remove_group(&input_dev->dev.kobj, &light_attribute_group); err_sysfs_create_group_light: input_unregister_device(cm3663->light_input_dev); err_input_register_device_light: err_input_allocate_device_light: destroy_workqueue(cm3663->prox_wq); err_create_prox_workqueue: destroy_workqueue(cm3663->light_wq); err_create_light_workqueue: sysfs_remove_group(&cm3663->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: input_unregister_device(cm3663->proximity_input_dev); err_input_register_device_proximity: err_input_allocate_device_proximity: free_irq(cm3663->irq, 0); err_setup_irq: err_setup_reg: mutex_destroy(&cm3663->power_lock); wake_lock_destroy(&cm3663->prx_wake_lock); kfree(cm3663); done: return ret; }
int akm8963_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct akm8963_data *akm; int err; pr_info("%s is called.\n", __func__); if (client->dev.platform_data == NULL && client->irq == 0) { dev_err(&client->dev, "platform data & irq are NULL.\n"); err = -ENODEV; goto exit_platform_data_null; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C check failed, exiting.\n"); err = -ENODEV; goto exit_check_functionality_failed; } akm = kzalloc(sizeof(struct akm8963_data), GFP_KERNEL); if (!akm) { dev_err(&client->dev, "failed to allocate memory for module data\n"); err = -ENOMEM; goto exit_alloc_data_failed; } akm->pdata = client->dev.platform_data; mutex_init(&akm->lock); init_completion(&akm->data_ready); i2c_set_clientdata(client, akm); akm->this_client = client; err = akm8963_ecs_set_mode_power_down(akm); if (err < 0) { pr_err("%s: akm8963_ecs_set_mode_power_down fail(err=%d)\n", __func__, err); goto exit_set_mode_power_down_failed; } err = akm8963_setup_irq(akm); if (err) { pr_err("%s: could not setup irq\n", __func__); goto exit_setup_irq; } akm->akmd_device.minor = MISC_DYNAMIC_MINOR; akm->akmd_device.name = "akm8963"; akm->akmd_device.fops = &akmd_fops; err = misc_register(&akm->akmd_device); if (err) { pr_err("%s, misc_register failed.\n", __func__); goto exit_akmd_device_register_failed; } init_waitqueue_head(&akm->state_wq); /* put into fuse access mode to read asa data */ err = i2c_smbus_write_byte_data(client, AK8963_REG_CNTL1, AK8963_CNTL1_FUSE_ACCESS); if (err) { pr_err("%s: unable to enter fuse rom mode\n", __func__); goto exit_i2c_failed; } err = i2c_smbus_read_i2c_block_data(client, AK8963_FUSE_ASAX, sizeof(akm->asa), akm->asa); if (err != sizeof(akm->asa)) { pr_err("%s: unable to load factory sensitivity adjust values\n", __func__); goto exit_i2c_failed; } else pr_info("%s: asa_x = %d, asa_y = %d, asa_z = %d\n", __func__, akm->asa[0], akm->asa[1], akm->asa[2]); err = i2c_smbus_write_byte_data(client, AK8963_REG_CNTL1, AK8963_CNTL1_POWER_DOWN); if (err) { dev_err(&client->dev, "Error in setting power down mode\n"); goto exit_i2c_failed; } akm->dev = sensors_classdev_register("magnetic_sensor"); if (IS_ERR(akm->dev)) { pr_err("Failed to create device!"); goto exit_class_create_failed; } if (device_create_file(akm->dev, &dev_attr_raw_data) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_raw_data.attr.name); goto exit_device_create_raw_data; } if (device_create_file(akm->dev, &dev_attr_vendor) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_name.attr.name); goto exit_device_create_vendor; } if (device_create_file(akm->dev, &dev_attr_name) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_raw_data.attr.name); goto exit_device_create_name; } #ifdef FACTORY_TEST if (device_create_file(akm->dev, &dev_attr_adc) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_adc.attr.name); goto exit_device_create_file1; } if (device_create_file(akm->dev, &dev_attr_status) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_status.attr.name); goto exit_device_create_file2; } if (device_create_file(akm->dev, &dev_attr_asa) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_asa.attr.name); goto exit_device_create_file3; } if (device_create_file(akm->dev, &dev_attr_selftest) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_selftest.attr.name); goto exit_device_create_file4; } if (device_create_file(akm->dev, &dev_attr_chk_registers) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_chk_registers.attr.name); goto exit_device_create_file5; } if (device_create_file(akm->dev, &dev_attr_dac) < 0) { pr_err("Failed to create device file(%s)!\n", dev_attr_dac.attr.name); goto exit_device_create_file6; } #endif dev_set_drvdata(akm->dev, akm); pr_info("%s is successful.\n", __func__); return 0; #ifdef FACTORY_TEST exit_device_create_file6: device_remove_file(akm->dev, &dev_attr_chk_registers); exit_device_create_file5: device_remove_file(akm->dev, &dev_attr_selftest); exit_device_create_file4: device_remove_file(akm->dev, &dev_attr_asa); exit_device_create_file3: device_remove_file(akm->dev, &dev_attr_status); exit_device_create_file2: device_remove_file(akm->dev, &dev_attr_adc); exit_device_create_file1: device_remove_file(akm->dev, &dev_attr_name); #endif exit_device_create_name: device_remove_file(akm->dev, &dev_attr_vendor); exit_device_create_vendor: device_remove_file(akm->dev, &dev_attr_raw_data); exit_device_create_raw_data: sensors_classdev_unregister(akm->dev); exit_class_create_failed: exit_i2c_failed: misc_deregister(&akm->akmd_device); exit_akmd_device_register_failed: free_irq(akm->irq, akm); gpio_free(akm->pdata->gpio_data_ready_int); exit_setup_irq: exit_set_mode_power_down_failed: mutex_destroy(&akm->lock); kfree(akm); exit_alloc_data_failed: exit_check_functionality_failed: exit_platform_data_null: return err; }
static int lightsensor_probe(struct platform_device *pdev) { struct sensor_data *data = NULL; int rt = -ENXIO; unsigned char get_data = 0; pr_info("%s, is called\n", __func__); /* Check I2C communication */ rt = opt_i2c_read(DATA0_LSB, &get_data, sizeof(get_data)); if (rt < 0) { pr_err("%s failed : threre is no such device.\n", __func__); return rt; } gprintk("probe start!\n"); data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL); if (!data) { pr_err("%s: failed to alloc memory for module data\n", __func__); return -ENOMEM; } data->enabled = 0; data->delay = SENSOR_DEFAULT_DELAY; data->input_dev = input_allocate_device(); if (!data->input_dev) { pr_err("%s: could not allocate input device\n", __func__); rt = -ENOMEM; goto err_input_allocate_device_light; } input_set_capability(data->input_dev, EV_REL, REL_MISC); data->input_dev->name = SENSOR_NAME; rt = input_register_device(data->input_dev); if (rt) { pr_err("%s: could not register input device\n", __func__); input_free_device(data->input_dev); goto err_input_register_device_light; } input_set_drvdata(data->input_dev, data); rt = sysfs_create_group(&data->input_dev->dev.kobj, &lightsensor_attribute_group); if (rt) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } mutex_init(&data->mutex); mutex_init(&data->light_mutex); data->light_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(data->light_dev)) { pr_err("%s: could not create light_dev\n", __func__); goto err_light_device_create; } if (device_create_file(data->light_dev, &dev_attr_lux) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lux.attr.name); goto err_light_device_create_file; } if (device_create_file(data->light_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_light_device_create_file1; } if (device_create_file(data->light_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_light_device_create_file2; } if (device_create_file(data->light_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_light_device_create_file3; } dev_set_drvdata(data->light_dev, data); data->wq = create_singlethread_workqueue("gp2a_wq"); if (!data->wq) { rt = -ENOMEM; pr_err("%s: could not create workqueue\n", __func__); goto err_create_workqueue; } /* this is the thread function we run on the work queue */ INIT_DELAYED_WORK(&data->work, gp2a_work_func_light); /* set platdata */ platform_set_drvdata(pdev, data); gprintk("probe success!\n"); goto done; /* error, unwind it all */ err_light_device_create_file3: device_remove_file(data->light_dev, &dev_attr_raw_data); err_light_device_create_file2: device_remove_file(data->light_dev, &dev_attr_name); err_light_device_create_file1: device_remove_file(data->light_dev, &dev_attr_vendor); err_create_workqueue: device_remove_file(data->light_dev, &dev_attr_lux); err_light_device_create_file: sensors_classdev_unregister(data->light_dev); err_light_device_create: mutex_destroy(&data->mutex); sysfs_remove_group(&data->input_dev->dev.kobj, &lightsensor_attribute_group); err_sysfs_create_group_light: input_unregister_device(data->input_dev); err_input_register_device_light: err_input_allocate_device_light: kfree(data); done: return rt; }
int fts_sensor_init(struct fts_ts_data *data) { struct fts_psensor_platform_data *psensor_pdata; struct input_dev *psensor_input_dev; int err; if (fts_psensor_support_enabled() ) { device_init_wakeup(&data->client->dev, 1); psensor_pdata = devm_kzalloc(&data->client->dev, sizeof(struct fts_psensor_platform_data), GFP_KERNEL); if (!psensor_pdata) { FTS_ERROR("Failed to allocate memory"); goto irq_free; } data->psensor_pdata = psensor_pdata; psensor_input_dev = input_allocate_device(); if (!psensor_input_dev) { FTS_ERROR("Failed to allocate device"); goto free_psensor_pdata; } __set_bit(EV_ABS, psensor_input_dev->evbit); input_set_abs_params(psensor_input_dev, ABS_DISTANCE, 0, 1, 0, 0); psensor_input_dev->name = "proximity"; psensor_input_dev->id.bustype = BUS_I2C; psensor_input_dev->dev.parent = &data->client->dev; data->psensor_pdata->input_psensor_dev = psensor_input_dev; err = input_register_device(psensor_input_dev); if (err) { FTS_ERROR("Unable to register device, err=%d", err); goto free_psensor_input_dev; } psensor_pdata->ps_cdev = sensors_proximity_cdev; psensor_pdata->ps_cdev.sensors_enable = fts_psensor_enable_set; psensor_pdata->data = data; err = sensors_classdev_register(&data->client->dev, &psensor_pdata->ps_cdev); if (err) { goto unregister_psensor_input_device; } } return 0; unregister_psensor_input_device: if (fts_psensor_support_enabled() ) input_unregister_device(data->psensor_pdata->input_psensor_dev); free_psensor_input_dev: if (fts_psensor_support_enabled() ) input_free_device(data->psensor_pdata->input_psensor_dev); free_psensor_pdata: if (fts_psensor_support_enabled() ) { devm_kfree(&data->client->dev, psensor_pdata); data->psensor_pdata = NULL; } irq_free: if (fts_psensor_support_enabled()) device_init_wakeup(&data->client->dev, 0); free_irq(data->client->irq, data); return 1; }
static int cm36686_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm36686_data *cm36686 = NULL; pr_info("%s is called.\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } cm36686 = kzalloc(sizeof(struct cm36686_data), GFP_KERNEL); if (!cm36686) { pr_err("%s: failed to alloc memory for cm36686 module data\n", __func__); return -ENOMEM; } cm36686->pdata = client->dev.platform_data; cm36686->i2c_client = client; i2c_set_clientdata(client, cm36686); mutex_init(&cm36686->power_lock); mutex_init(&cm36686->read_lock); if(cm36686->pdata->cm36686_light_power != NULL) { cm36686->cm36686_light_vddpower = cm36686->pdata->cm36686_light_power; if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(true); } if(cm36686->pdata->cm36686_proxi_power != NULL) { cm36686->cm36686_proxi_vddpower = cm36686->pdata->cm36686_proxi_power; if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(true); } /* wake lock init for proximity sensor */ wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); if (cm36686->pdata->cm36686_led_on) { cm36686->pdata->cm36686_led_on(true); msleep(20); } /* Check if the device is there or not. */ ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001); if (ret < 0) { pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret); goto err_setup_reg; } /* setup initial registers */ ret = cm36686_setup_reg(cm36686); if (ret < 0) { pr_err("%s: could not setup regs\n", __func__); goto err_setup_reg; } if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(false); if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(false); /* allocate proximity input_device */ cm36686->proximity_input_dev = input_allocate_device(); if (!cm36686->proximity_input_dev) { pr_err("%s: could not allocate proximity input device\n", __func__); goto err_input_allocate_device_proximity; } input_set_drvdata(cm36686->proximity_input_dev, cm36686); cm36686->proximity_input_dev->name = "proximity_sensor"; input_set_capability(cm36686->proximity_input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(cm36686->proximity_input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = input_register_device(cm36686->proximity_input_dev); if (ret < 0) { input_free_device(cm36686->proximity_input_dev); pr_err("%s: could not register input device\n", __func__); goto err_input_register_device_proximity; } ret = sysfs_create_group(&cm36686->proximity_input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } #if defined(CONFIG_SENSOR_USE_SYMLINK) ret = sensors_initialize_symlink(cm36686->proximity_input_dev); if (ret < 0) { pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n", __func__, ret); goto err_setup_irq; } #endif /* setup irq */ ret = cm36686_setup_irq(cm36686); if (ret) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } /* For factory test mode, we use timer to get average proximity data. */ /* prox_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/ cm36686->prox_timer.function = cm36686_prox_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq"); if (!cm36686->prox_wq) { ret = -ENOMEM; pr_err("%s: could not create prox workqueue\n", __func__); goto err_create_prox_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox); /* allocate lightsensor input_device */ cm36686->light_input_dev = input_allocate_device(); if (!cm36686->light_input_dev) { pr_err("%s: could not allocate light input device\n", __func__); goto err_input_allocate_device_light; } input_set_drvdata(cm36686->light_input_dev, cm36686); cm36686->light_input_dev->name = "light_sensor"; input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC); input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL); input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL); ret = input_register_device(cm36686->light_input_dev); if (ret < 0) { input_free_device(cm36686->light_input_dev); pr_err("%s: could not register input device\n", __func__); goto err_input_register_device_light; } ret = sysfs_create_group(&cm36686->light_input_dev->dev.kobj, &light_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } #if defined(CONFIG_SENSOR_USE_SYMLINK) ret = sensors_initialize_symlink(cm36686->light_input_dev); if (ret < 0) { pr_err("%s - light_sensors_initialize_symlink error(%d).\n", __func__, ret); goto err_create_light_workqueue; } #endif /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); cm36686->light_timer.function = cm36686_light_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ cm36686->light_wq = create_singlethread_workqueue("cm36686_light_wq"); if (!cm36686->light_wq) { ret = -ENOMEM; pr_err("%s: could not create light workqueue\n", __func__); goto err_create_light_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&cm36686->work_light, cm36686_work_func_light); /* set sysfs for proximity sensor */ cm36686->proximity_dev = sensors_classdev_register("proximity_sensor"); if (IS_ERR(cm36686->proximity_dev)) { pr_err("%s: could not create proximity_dev\n", __func__); goto err_proximity_device_create; } if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_state.attr.name); goto err_proximity_device_create_file1; } if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, attr_prox_raw.attr.name); goto err_proximity_device_create_file2; } #ifdef CM36686_CANCELATION if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_cal) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_cal.attr.name); goto err_proximity_device_create_file3; } if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_offset_pass.attr.name); goto err_proximity_device_create_file4; } #endif if (device_create_file(cm36686->proximity_dev, &dev_attr_prox_avg) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_prox_avg.attr.name); goto err_proximity_device_create_file5; } if (device_create_file(cm36686->proximity_dev, &dev_attr_thresh_high) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_thresh_high.attr.name); goto err_proximity_device_create_file6; } if (device_create_file(cm36686->proximity_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_proximity_device_create_file7; } if (device_create_file(cm36686->proximity_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_proximity_device_create_file8; } if (device_create_file(cm36686->proximity_dev, &dev_attr_thresh_low) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_thresh_low.attr.name); goto err_proximity_device_create_file9; } dev_set_drvdata(cm36686->proximity_dev, cm36686); /* set sysfs for light sensor */ cm36686->light_dev = sensors_classdev_register("light_sensor"); if (IS_ERR(cm36686->light_dev)) { pr_err("%s: could not create light_dev\n", __func__); goto err_light_device_create; } if (device_create_file(cm36686->light_dev, &dev_attr_lux) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_lux.attr.name); goto err_light_device_create_file1; } if (device_create_file(cm36686->light_dev, &dev_attr_raw_data) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_raw_data.attr.name); goto err_light_device_create_file2; } if (device_create_file(cm36686->light_dev, &dev_attr_vendor) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_vendor.attr.name); goto err_light_device_create_file3; } if (device_create_file(cm36686->light_dev, &dev_attr_name) < 0) { pr_err("%s: could not create device file(%s)!\n", __func__, dev_attr_name.attr.name); goto err_light_device_create_file4; } dev_set_drvdata(cm36686->light_dev, cm36686); pr_info("%s is success.\n", __func__); goto done; /* error, unwind it all */ err_light_device_create_file4: device_remove_file(cm36686->light_dev, &dev_attr_vendor); err_light_device_create_file3: device_remove_file(cm36686->light_dev, &dev_attr_raw_data); err_light_device_create_file2: device_remove_file(cm36686->light_dev, &dev_attr_lux); err_light_device_create_file1: sensors_classdev_unregister(cm36686->light_dev); err_light_device_create: device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low); err_proximity_device_create_file9: device_remove_file(cm36686->proximity_dev, &dev_attr_name); err_proximity_device_create_file8: device_remove_file(cm36686->proximity_dev, &dev_attr_vendor); err_proximity_device_create_file7: device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high); err_proximity_device_create_file6: device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg); err_proximity_device_create_file5: #ifdef CM36686_CANCELATION device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass); err_proximity_device_create_file4: device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal); err_proximity_device_create_file3: #endif device_remove_file(cm36686->proximity_dev, &attr_prox_raw); err_proximity_device_create_file2: device_remove_file(cm36686->proximity_dev, &dev_attr_state); err_proximity_device_create_file1: sensors_classdev_unregister(cm36686->proximity_dev); err_proximity_device_create: destroy_workqueue(cm36686->light_wq); err_create_light_workqueue: sysfs_remove_group(&cm36686->light_input_dev->dev.kobj, &light_attribute_group); err_sysfs_create_group_light: input_unregister_device(cm36686->light_input_dev); err_input_register_device_light: err_input_allocate_device_light: destroy_workqueue(cm36686->prox_wq); err_create_prox_workqueue: free_irq(cm36686->irq, cm36686); gpio_free(cm36686->pdata->irq); err_setup_irq: sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: input_unregister_device(cm36686->proximity_input_dev); err_input_register_device_proximity: err_input_allocate_device_proximity: err_setup_reg: if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); if (cm36686->cm36686_light_vddpower) cm36686->cm36686_light_vddpower(false); if (cm36686->cm36686_proxi_vddpower) cm36686->cm36686_proxi_vddpower(false); wake_lock_destroy(&cm36686->prx_wake_lock); mutex_destroy(&cm36686->read_lock); mutex_destroy(&cm36686->power_lock); kfree(cm36686); done: return ret; }
static int __devinit mma8x5x_probe(struct i2c_client *client, const struct i2c_device_id *id) { int result, chip_id; struct input_dev *idev; struct mma8x5x_data *pdata; struct i2c_adapter *adapter; adapter = to_i2c_adapter(client->dev.parent); /* power on the device */ result = mma8x5x_config_regulator(client, 1); if (result) goto err_power_on; result = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA); if (!result) goto err_check_id; chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I); if (!mma8x5x_check_id(chip_id)) { dev_err(&client->dev, "read chip ID 0x%x is not equal to 0x%x,0x%x,0x%x,0x%x,0x%x!\n", chip_id, MMA8451_ID, MMA8452_ID, MMA8453_ID, MMA8652_ID, MMA8653_ID); result = -EINVAL; goto err_check_id; } /* set the private data */ pdata = kzalloc(sizeof(struct mma8x5x_data), GFP_KERNEL); if (!pdata) { result = -ENOMEM; dev_err(&client->dev, "alloc data memory error!\n"); goto err_check_id; } if (client->dev.of_node) { result = mma8x5x_parse_dt(&client->dev, pdata); if (result) goto err_parse_dt; } else { pdata->position = CONFIG_SENSORS_MMA_POSITION; pdata->int_pin = -1; pdata->int_flags = 0; } /* Initialize the MMA8X5X chip */ pdata->client = client; pdata->chip_id = chip_id; pdata->mode = MODE_2G; pdata->poll_delay = POLL_INTERVAL; mutex_init(&pdata->data_lock); i2c_set_clientdata(client, pdata); /* Initialize the MMA8X5X chip */ mma8x5x_device_init(client); if (pdata->use_int) { if (pdata->int_pin >= 0) client->irq = gpio_to_irq(pdata->int_pin); if (gpio_is_valid(pdata->int_pin)) { result = gpio_request(pdata->int_pin, "mma8x5x_irq_gpio"); if (result) { dev_err(&client->dev, "irq gpio(%d) request failed", pdata->int_pin); goto err_request_gpio; } result = gpio_direction_input(pdata->int_pin); if (result) { dev_err(&client->dev, "set_direction for irq gpio failed\n"); goto err_set_gpio_direction; } } device_init_wakeup(&client->dev, true); enable_irq_wake(client->irq); result = request_threaded_irq(client->irq, NULL, mma8x5x_interrupt, IRQ_TYPE_EDGE_RISING | IRQF_ONESHOT | IRQF_NO_SUSPEND, ACCEL_INPUT_DEV_NAME, (void *)client); if (result) { dev_err(&client->dev, "Could not allocate irq(%d) !\n", client->irq); goto err_register_irq; } mma8x5x_device_int_init(client); } else { INIT_DELAYED_WORK(&pdata->dwork, mma8x5x_dev_poll); } idev = input_allocate_device(); if (!idev) { result = -ENOMEM; dev_err(&client->dev, "alloc input device failed!\n"); goto err_alloc_poll_device; } input_set_drvdata(idev, pdata); idev->name = ACCEL_INPUT_DEV_NAME; idev->uniq = mma8x5x_id2name(pdata->chip_id); idev->id.bustype = BUS_I2C; idev->evbit[0] = BIT_MASK(EV_ABS); input_set_abs_params(idev, ABS_X, -0x7fff, 0x7fff, 0, 0); input_set_abs_params(idev, ABS_Y, -0x7fff, 0x7fff, 0, 0); input_set_abs_params(idev, ABS_Z, -0x7fff, 0x7fff, 0, 0); result = input_register_device(idev); if (result) { dev_err(&client->dev, "register input device failed!\n"); goto err_register_device; } pdata->idev = idev; result = sysfs_create_group(&idev->dev.kobj, &mma8x5x_attr_group); if (result) { dev_err(&client->dev, "create device file failed!\n"); result = -EINVAL; goto err_create_sysfs; } pdata->cdev = sensors_cdev; pdata->cdev.min_delay = POLL_INTERVAL_MIN * 1000; pdata->cdev.delay_msec = pdata->poll_delay; pdata->cdev.sensors_enable = mma8x5x_enable_set; pdata->cdev.sensors_poll_delay = mma8x5x_poll_delay_set; result = sensors_classdev_register(&client->dev, &pdata->cdev); if (result) { dev_err(&client->dev, "create class device file failed!\n"); result = -EINVAL; goto err_create_class_sysfs; } dev_info(&client->dev, "%s:mma8x5x device driver probe successfully, position =%d\n", __func__, pdata->position); return 0; err_create_class_sysfs: sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group); err_create_sysfs: input_unregister_device(idev); err_register_device: input_free_device(idev); err_alloc_poll_device: err_register_irq: if (pdata->use_int) device_init_wakeup(&client->dev, false); err_set_gpio_direction: if (gpio_is_valid(pdata->int_pin) && pdata->use_int) gpio_free(pdata->int_pin); err_request_gpio: err_parse_dt: kfree(pdata); err_check_id: mma8x5x_config_regulator(client, 0); err_power_on: return result; }
static int __devinit lsm303dlhc_mag_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct lsm303dlhc_mag_platform_data *pdata = client->dev.platform_data; struct lsm303dlhc_mag_data *mag; int result = 0; dev_info(&client->dev, "%s \n", __func__); if (!pdata) { result = -EINVAL; dev_err(&client->dev, "%s: platform data required.\n", __func__); goto err_no_platform_data; } mag = kzalloc(sizeof(*mag), GFP_KERNEL); if (NULL == mag) { result = -ENOMEM; goto err_alloc_data_failed; } mag->client = client; mag->poll_interval_ms = pdata->poll_interval_ms; mag->range = pdata->range; dev_info(&client->dev, "%s:pdata->range:%d\n", __func__, pdata->range); i2c_set_clientdata(client, mag); if (pdata->power_on) mag->power_on = pdata->power_on; else mag->power_on = lsm303dlhc_mag_power_stub; if (pdata->power_off) mag->power_off = pdata->power_off; else mag->power_off = lsm303dlhc_mag_power_stub; mag->power_on(); lsm303dlhc_mag_config_regulator( mag , true); msleep(500); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { result = -EIO; goto err_check_functionality; } result = i2c_smbus_write_byte_data(client, MR_REG_M, IDLE_MODE); mag->power_off(); lsm303dlhc_mag_config_regulator( mag , false); if (result) { dev_err(&client->dev, "%s: Device not responding.\n", __func__); goto err_not_responding; } INIT_DELAYED_WORK(&mag->work, lsm303dlhc_mag_poll_func); mutex_init(&mag->lock); mag->dev = sensors_classdev_register("magnetometer"); result = create_sysfs_interfaces(mag->dev); if (result) goto err_sys_attr; dev_set_drvdata(mag->dev, mag); mag->input_dev = input_allocate_device(); if (!mag->input_dev) { dev_err(&client->dev, "%s: input_allocate_device failed\n", __func__); result = -ENOMEM; goto err_allocate_device; } input_set_drvdata(mag->input_dev, mag); mag->input_dev->name = "magnetometer"; set_bit(EV_ABS, mag->input_dev->evbit); set_bit(ABS_X, mag->input_dev->absbit); set_bit(ABS_Y, mag->input_dev->absbit); set_bit(ABS_Z, mag->input_dev->absbit); input_set_abs_params(mag->input_dev, ABS_X, -MAG_RANGE_MG, MAG_RANGE_MG - 1, 0, 0); input_set_abs_params(mag->input_dev, ABS_Y, -MAG_RANGE_MG, MAG_RANGE_MG - 1, 0, 0); input_set_abs_params(mag->input_dev, ABS_Z, -MAG_RANGE_MG, MAG_RANGE_MG - 1, 0, 0); result = input_register_device(mag->input_dev); if (result) { dev_err(&client->dev, "%s: input_register_device failed!", __func__); goto err_register_device; } dev_set_drvdata(&mag->input_dev->dev, mag); if (device_create_file(&mag->input_dev->dev, &dev_attr_enable) < 0) { pr_err("%s: Failed to create device file(%s)!\n", __func__, dev_attr_enable.attr.name); goto err_check_functionality; } mag->irq_m = pdata->irq_m; if (mag->irq_m > 0) { /* interrupt */ mag->interruptible = true; result = request_threaded_irq(gpio_to_irq(mag->irq_m), NULL, lsm303dlhc_m_gpio_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "lsm303dlhc_m", mag); if (result) { dev_err(&client->dev, "request irq EGPIO_PIN_1 failed\n"); goto err_check_functionality; } disable_irq(gpio_to_irq(mag->irq_m)); } mag->interruptible = false; dev_info(&client->dev, "%s mag->interruptible=%d completed.\n", __func__, mag->interruptible); return 0; err_register_device: input_free_device(mag->input_dev); err_allocate_device: remove_sysfs_interfaces(mag->dev); err_sys_attr: err_not_responding: kfree(mag); err_alloc_data_failed: err_no_platform_data: err_check_functionality: dev_err(&client->dev, "%s failed.\n", __func__); return result; }