static int cm3323_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm3323_p *data = NULL; pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct cm3323_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } data->i2c_client = client; i2c_set_clientdata(client, data); /* Check if the device is there or not. */ ret = cm3323_setup_reg(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup regs\n", __func__); goto exit_setup_reg; } /* input device init */ ret = cm3323_input_init(data); if (ret < 0) goto exit_input_init; atomic_set(&data->delay, CM3323_DEFAULT_DELAY); data->time_count = 0; INIT_DELAYED_WORK(&data->work, cm3323_work_func_light); /* set sysfs for light sensor */ sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME); pr_info("[SENSOR]: %s - Probe done!\n", __func__); return 0; exit_input_init: exit_setup_reg: kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; }
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 cm3323_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm3323_p *data = NULL; pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct cm3323_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } data->i2c_client = client; i2c_set_clientdata(client, data); mutex_init(&data->power_lock); mutex_init(&data->read_lock); /* Check if the device is there or not. */ ret = cm3323_setup_reg(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup regs\n", __func__); goto exit_setup_reg; } /* input device init */ ret = cm3323_input_init(data); if (ret < 0) goto exit_input_init; /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&data->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); data->light_timer.function = cm3323_light_timer_func; data->time_count = 0; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ data->light_wq = create_singlethread_workqueue("cm3323_light_wq"); if (!data->light_wq) { ret = -ENOMEM; pr_err("[SENSOR]: %s - could not create light workqueue\n", __func__); goto exit_create_light_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&data->work_light, cm3323_work_func_light); /* set sysfs for light sensor */ sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME); pr_info("[SENSOR]: %s - Probe done!\n", __func__); return 0; exit_create_light_workqueue: sysfs_remove_group(&data->input->dev.kobj, &light_attribute_group); sensors_remove_symlink(&data->input->dev.kobj, data->input->name); input_unregister_device(data->input); exit_input_init: exit_setup_reg: mutex_destroy(&data->read_lock); mutex_destroy(&data->power_lock); kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; }