static void hall_device_irq_enable(struct hall_device_irq * irq, bool enable, bool flag_sync) { if (enable == irq->enabled) { SENSOR_LOG_INFO("doubule %s irq %d, retern here\n",enable? "enable" : "disable", irq->irq_num); return; } else { irq->enabled = enable; SENSOR_LOG_INFO("%s irq %d\n",enable? "enable" : "disable",irq->irq_num); } if (enable) { enable_irq(irq->irq_num); } else { if (flag_sync) { disable_irq(irq->irq_num); } else { disable_irq_nosync(irq->irq_num); } } }
static int sensor_compass_int_pin_init(int pin_num) { int ret = 0; ret = gpio_request(pin_num, "compass_int"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",COMPASS_INT_PIN); gpio_free(pin_num); ret = gpio_request(pin_num, "compass_int"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",COMPASS_INT_PIN); return ret; } } else { SENSOR_LOG_INFO("gpio %d get success\n",COMPASS_INT_PIN); } ret = gpio_tlmm_config(GPIO_CFG(pin_num, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (ret < 0) { SENSOR_LOG_ERROR("gpio_tlmm_config failed ret = %d",ret); } return ret; }
static void hall_device_check_state(struct hall_device_chip *chip) { int pin_state_n = -1; int pin_state_s = -1; pin_state_n = gpio_get_value(chip->irq_n.irq_pin); pin_state_s = gpio_get_value(chip->irq_s.irq_pin); if ((1==pin_state_n) && (1==pin_state_s)) { SENSOR_LOG_INFO("MAGNETIC_DEVICE FAR\n"); input_report_rel(chip->idev, REL_RX, MAGNETIC_DEVICE_FAR); input_sync(chip->idev); } else { if ((0==pin_state_n) || (0==pin_state_s)) { SENSOR_LOG_INFO("MAGNETIC_DEVICE NEAR\n"); input_report_rel(chip->idev, REL_RX, MAGNETIC_DEVICE_NEAR); input_sync(chip->idev); } } };
static int __devinit maxq616_probe(struct i2c_client *client, const struct i2c_device_id *id) { static struct maxq616_chip *chip; int ret; SENSOR_LOG_INFO("prob start\n"); chip = kzalloc(sizeof(struct maxq616_chip), GFP_KERNEL); if (!chip) { ret = -ENOMEM; goto malloc_chip_failed; } maxq616_chip_data_init(chip); chip->client = client; i2c_set_clientdata(client, chip); maxq616_power_init(chip); maxq616_power_on(chip, true); SENSOR_LOG_INFO("prob success\n"); return 0; malloc_chip_failed: SENSOR_LOG_INFO("prob failed\n"); return ret; }
static void hall_device_flush_work_func(struct work_struct *work) { struct hall_device_chip *chip = container_of(work, struct hall_device_chip, flush_work.work); SENSOR_LOG_INFO("prob Enter\n"); hall_device_check_state(chip); SENSOR_LOG_INFO("prob Exit\n"); }
static void hall_device_irq_work_n(struct work_struct *work) { struct hall_device_chip *chip = container_of(work, struct hall_device_chip, irq_work_n); mutex_lock(&chip->lock); //SENSOR_LOG_INFO("enter\n"); if (0 == gpio_get_value(chip->irq_n.irq_pin)) { SENSOR_LOG_INFO("MAGNETIC_DEVICE NEAR\n"); input_report_rel(chip->idev, REL_RX, MAGNETIC_DEVICE_NEAR); hall_device_wakelock_ops(&(chip->wakeup_wakelock),false); } else { SENSOR_LOG_INFO("MAGNETIC_DEVICE FAR\n"); input_report_rel(chip->idev, REL_RX, MAGNETIC_DEVICE_FAR); hrtimer_start(&chip->unlock_wakelock_timer, ktime_set(3, 0), HRTIMER_MODE_REL); } input_sync(chip->idev); chip->on_irq_working = false; hall_device_irq_enable(&(chip->irq_n), true, true); //SENSOR_LOG_INFO("exit\n"); mutex_unlock(&chip->lock); };
static void hall_device_irq_work_n(struct work_struct *work) { struct hall_device_chip *chip = container_of(work, struct hall_device_chip, irq_work_n); unsigned int hall_device_state; mutex_lock(&chip->lock); hall_device_state = gpio_get_value(chip->irq_n.irq_pin) ? MAGNETIC_DEVICE_FAR : MAGNETIC_DEVICE_NEAR; if (hall_device_state==chip->state_n) { SENSOR_LOG_INFO("MAGNETIC_DEVICE N [%s] same state\n",hall_device_state==1? "NEAR" : "FAR"); } else { chip->state_n = hall_device_state; chip->state_s = gpio_get_value(chip->irq_s.irq_pin) ? MAGNETIC_DEVICE_FAR : MAGNETIC_DEVICE_NEAR; SENSOR_LOG_INFO("N is %s, S is %s\n",chip->state_n==1? "NEAR" : "FAR",chip->state_s==1? "NEAR" : "FAR"); input_report_rel(chip->idev, REL_RX, chip->state_s); input_report_rel(chip->idev, REL_RY, chip->state_n); input_sync(chip->idev); } if (chip->state_n==MAGNETIC_DEVICE_NEAR) { hall_device_wakelock_ops(&(chip->wakeup_wakelock),false); } else { hrtimer_start(&chip->unlock_wakelock_timer, ktime_set(3, 0), HRTIMER_MODE_REL); } chip->on_irq_working = false; hall_device_irq_enable(&(chip->irq_n), true, true); mutex_unlock(&chip->lock); };
static int __devinit sensor_common_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct sensor_common_data *chip_data; // struct device *dev = &client->dev; int ret; chip_data = kzalloc(sizeof(struct sensor_common_data), GFP_KERNEL); SENSOR_LOG_INFO("prob start\n"); i2c_set_clientdata(client, chip_data); sensor_common_class = class_create(THIS_MODULE, "sensor"); chip_data->sensor_compass_dev = device_create(sensor_common_class, NULL, sensor_compass_dev, &sensor_common_driver ,"compass"); if (IS_ERR(chip_data->sensor_compass_dev)) { ret = PTR_ERR(chip_data->sensor_compass_dev); goto create_sensor_compass_failed; } dev_set_drvdata(chip_data->sensor_compass_dev, chip_data); chip_data->sensor_temp_humidity_dev = device_create(sensor_common_class, NULL, sensor_temp_humidity_dev, &sensor_common_driver ,"temp_humidity"); if (IS_ERR(chip_data->sensor_temp_humidity_dev)) { ret = PTR_ERR(chip_data->sensor_temp_humidity_dev); goto create_sensor_sensor_temp_humidity_failed; } dev_set_drvdata(chip_data->sensor_temp_humidity_dev, chip_data); sensor_compass_create_sysfs_interfaces(chip_data->sensor_compass_dev); sensor_temp_humidity_create_sysfs_interfaces(chip_data->sensor_temp_humidity_dev); sensor_compass_int_pin_init(COMPASS_INT_PIN); SENSOR_LOG_INFO("prob success\n"); return 0; create_sensor_sensor_temp_humidity_failed: chip_data->sensor_compass_dev = NULL; class_destroy(sensor_common_class); create_sensor_compass_failed: chip_data->sensor_compass_dev = NULL; class_destroy(sensor_common_class); return ret; }
//suspend static int maxq616_suspend(struct device *dev) { struct maxq616_chip *chip = dev_get_drvdata(dev); if (0) { SENSOR_LOG_INFO("enter\n"); maxq616_power_on(chip, false); SENSOR_LOG_INFO("eixt\n"); } return 0 ; }
//suspend static int hall_device_suspend(struct device *dev) { struct hall_device_chip *chip = dev_get_drvdata(dev); SENSOR_LOG_INFO("enter\n"); if (true==chip->enabled) { enable_irq_wake(chip->irq_s.irq_num); enable_irq_wake(chip->irq_n.irq_num); } SENSOR_LOG_INFO("eixt\n"); return 0 ; }
static ssize_t hall_value_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hall_device_chip *chip = dev_get_drvdata(dev); SENSOR_LOG_INFO("\n"); schedule_delayed_work(&chip->flush_work, msecs_to_jiffies(200)); return strlen(buf); }
/** * maxq616_remove() - remove device * @client: I2C client device */ static int __devexit maxq616_remove(struct i2c_client *client) { struct maxq616_chip *chip = i2c_get_clientdata(client); kfree(chip); chip = NULL; SENSOR_LOG_INFO("maxq616_remove\n"); return 0; }
static int hall_device_parse_dt(struct hall_device_chip *chip) { struct device_node *np = chip->client->dev.of_node; chip->irq_s.irq_pin = of_get_named_gpio(np, "hall_device,s-irq-gpio", 0); chip->irq_n.irq_pin = of_get_named_gpio(np, "hall_device,n-irq-gpio", 0); SENSOR_LOG_INFO("irq_s.irq_pin is %d, irq_n.irq_pin is %d\n",chip->irq_s.irq_pin,chip->irq_n.irq_pin); return 0; }
/** * hall_device_remove() - remove device * @client: I2C client device */ static int __devexit hall_device_remove(struct i2c_client *client) { struct shtc1_data *chip_data = i2c_get_clientdata(client); SENSOR_LOG_INFO("hall_device_remove\n"); kfree(chip_data); return 0; }
static ssize_t compass_int_pin_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { bool value; if (strtobool(buf, &value)) return -EINVAL; if (value) { SENSOR_LOG_INFO("set to be 1\n"); gpio_set_value(COMPASS_INT_PIN, 1); } else { SENSOR_LOG_INFO("set to be 0\n"); gpio_set_value(COMPASS_INT_PIN, 0); } return size; }
static int maxq616_power_init(struct maxq616_chip *chip) { int rc; chip->power = regulator_get(&(chip->client->dev), "vdd-chip"); if (IS_ERR(chip->power)) { rc = PTR_ERR(chip->power); SENSOR_LOG_ERROR("Regulator get failed chip->power rc=%d\n", rc); return rc; } if (regulator_count_voltages(chip->power) > 0) { rc = regulator_set_voltage(chip->power, 1800000, 1800000); if (rc) { SENSOR_LOG_ERROR("Regulator set chip->power failed rc=%d\n", rc); goto error_set_voltage; } } rc = regulator_set_optimum_mode(chip->power, 600000); if (rc < 0) { SENSOR_LOG_ERROR("Regulator chip->power set_opt failed rc=%d\n", rc); goto error_set_optimum; } SENSOR_LOG_INFO("success\n"); return 0; error_set_optimum: regulator_set_voltage(chip->power, 0, 1800000); regulator_put(chip->power); error_set_voltage: regulator_put(chip->power); SENSOR_LOG_INFO("failed\n"); return rc; }
/** * sensor_common_remove() - remove device * @client: I2C client device */ static int __devexit sensor_common_remove(struct i2c_client *client) { struct sensor_common_data *chip_data = i2c_get_clientdata(client); SENSOR_LOG_INFO("sensor_common_remove\n"); //hwmon_device_unregister(chip_data->hwmon_dev); //sysfs_remove_group(&client->dev.kobj, &sensor_common_attr_group); kfree(chip_data); return 0; }
static void hall_device_check_state(struct hall_device_chip *chip) { chip->state_n = gpio_get_value(chip->irq_n.irq_pin) ? MAGNETIC_DEVICE_FAR : MAGNETIC_DEVICE_NEAR; chip->state_s = gpio_get_value(chip->irq_s.irq_pin) ? MAGNETIC_DEVICE_FAR : MAGNETIC_DEVICE_NEAR; SENSOR_LOG_INFO("N is %s, S is %s\n",chip->state_n==1? "NEAR" : "FAR",chip->state_s==1? "NEAR" : "FAR"); input_report_rel(chip->idev, REL_RX, chip->state_s); input_report_rel(chip->idev, REL_RY, chip->state_n); input_sync(chip->idev); };
static int maxq616_power_on(struct maxq616_chip *chip, bool enable) { int rc; if (enable == chip->power_on) { SENSOR_LOG_INFO("double %s power, retern here\n",enable? "enable" : "disable"); return 0; } else { SENSOR_LOG_INFO("%s power\n",enable? "enable" : "disable"); } if (enable) { rc = regulator_enable(chip->power); if (rc) { SENSOR_LOG_ERROR("Regulator chip->power enable failed rc=%d\n", rc); goto err_power_enable_failed; } chip->power_on = true; } else { rc = regulator_disable(chip->power); if (rc) { SENSOR_LOG_ERROR("Regulator chip->power enable failed rc=%d\n", rc); goto err_power_disable_failed; } chip->power_on = false; } return 0; err_power_enable_failed: err_power_disable_failed: return rc; }
static void hall_device_wakelock_ops(struct hall_device_wake_lock *wakelock, bool enable) { if (enable == wakelock->locked) { SENSOR_LOG_INFO("doubule %s %s, retern here\n",enable? "lock" : "unlock",wakelock->name); return; } if (enable) { wake_lock(&wakelock->lock); } else { wake_unlock(&wakelock->lock); } wakelock->locked = enable; SENSOR_LOG_INFO("%s %s \n",enable? "lock" : "unlock",wakelock->name); }
static ssize_t attr_raw_humidity_get(struct device *dev,struct device_attribute *attr, char *buf) { static int raw_humidity; raw_humidity = sensor_common_read_file_int(PATH_RAW_HUMIDITY); SENSOR_LOG_INFO("raw_humidity is %d\n",raw_humidity); /* sprintf(buf, "%d\n", raw_humidity); memcpy(buf, &raw_humidity, sizeof(int)); return sizeof(int); */ return sprintf(buf, "%d\n", raw_humidity); }
static ssize_t attr_raw_temp_get(struct device *dev,struct device_attribute *attr, char *buf) { static int raw_temp; raw_temp = sensor_common_read_file_int(PATH_RAW_TEMP); SENSOR_LOG_INFO("raw_temp is %d\n",raw_temp); /* sprintf(buf, "%d\n", raw_temp); memcpy(buf, &raw_temp, sizeof(int)); return sizeof(int); */ return sprintf(buf, "%d\n", raw_temp); }
static void hall_device_enable(struct hall_device_chip *chip, int on) { SENSOR_LOG_INFO("%s hall_device\n",on? "enable" : "disable"); if (on) { hall_device_irq_enable(&(chip->irq_s), true, true); hall_device_irq_enable(&(chip->irq_n), true, true); hall_device_check_state(chip); } else { hall_device_irq_enable(&(chip->irq_s), false, true); hall_device_irq_enable(&(chip->irq_n), false, true); } }
static irqreturn_t hall_device_irq_n(int irq, void *handle) { struct hall_device_chip *chip = handle; //SENSOR_LOG_INFO("enter\n"); hall_device_irq_enable(&(chip->irq_n), false, false); chip->on_irq_working = true; hrtimer_cancel(&chip->unlock_wakelock_timer); if (true == chip->enabled) { hall_device_wakelock_ops(&(chip->wakeup_wakelock),true); } if (0==schedule_work(&chip->irq_work_n)) { SENSOR_LOG_INFO("schedule_work failed!\n"); } //SENSOR_LOG_INFO("exit\n"); return IRQ_HANDLED; }
static void __exit maxq616_exit(void) { SENSOR_LOG_INFO("driver: exit\n"); i2c_del_driver(&maxq616_driver); }
static int __init maxq616_init(void) { SENSOR_LOG_INFO("driver: init\n"); return i2c_add_driver(&maxq616_driver); }
static void __exit hall_device_exit(void) { SENSOR_LOG_INFO("driver: exit\n"); i2c_del_driver(&hall_device_driver); }
static void __exit sensor_common_exit(void) { SENSOR_LOG_INFO("driver: exit\n"); i2c_del_driver(&sensor_common_driver); }
static int __init sensor_common_init(void) { SENSOR_LOG_INFO("driver: init\n"); return i2c_add_driver(&sensor_common_driver); }
static int __devinit hall_device_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; static struct hall_device_chip *chip; SENSOR_LOG_INFO("prob start\n"); chip = kzalloc(sizeof(struct hall_device_chip), GFP_KERNEL); if (!chip) { ret = -ENOMEM; goto malloc_failed; } chip->client = client; i2c_set_clientdata(client, chip); hall_device_chip_data_init(chip); hall_device_parse_dt(chip); SENSOR_LOG_INFO("hall_device_int_s is %d",chip->irq_s.irq_pin); SENSOR_LOG_INFO("hall_device_int_n is %d",chip->irq_n.irq_pin); mutex_init(&chip->lock); hall_device_class = class_create(THIS_MODULE, "hall_device"); chip->hall_device_dev = device_create(hall_device_class, NULL, hall_device_dev_t, &hall_device_driver ,"hall_device"); if (IS_ERR(chip->hall_device_dev)) { ret = PTR_ERR(chip->hall_device_dev); goto create_hall_device_dev_failed; } dev_set_drvdata(chip->hall_device_dev, chip); ret = gpio_request(chip->irq_s.irq_pin, "chip->irq_s.irq_pin"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_s.irq_pin); gpio_free(chip->irq_s.irq_pin); ret = gpio_request(chip->irq_s.irq_pin, "chip->irq_s.irq_pin"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_s.irq_pin); return ret; } } ret = gpio_tlmm_config(GPIO_CFG(chip->irq_s.irq_pin, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE); chip->irq_s.irq_num = gpio_to_irq(chip->irq_s.irq_pin); INIT_WORK(&chip->irq_work_s, hall_device_irq_work_s); ret = request_threaded_irq(chip->irq_s.irq_num, NULL, &hall_device_irq_s, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "hall_device_irq_s", chip); if (ret) { SENSOR_LOG_ERROR("Failed to request irq %d\n", chip->irq_s.irq_num); goto irq_s_register_fail; } ret = gpio_request(chip->irq_n.irq_pin, "chip->irq_n.irq_pin"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_n.irq_pin); gpio_free(chip->irq_n.irq_pin); ret = gpio_request(chip->irq_n.irq_pin, "chip->irq_n.irq_pin"); if (ret) { SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_n.irq_pin); return ret; } } ret = gpio_tlmm_config(GPIO_CFG(chip->irq_n.irq_pin, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE); chip->irq_n.irq_num = gpio_to_irq(chip->irq_n.irq_pin); INIT_WORK(&chip->irq_work_n, hall_device_irq_work_n); ret = request_threaded_irq(chip->irq_n.irq_num , NULL, &hall_device_irq_n, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "hall_device_irq_n", chip); if (ret) { SENSOR_LOG_ERROR("Failed to request irq %d\n", chip->irq_n.irq_num ); goto irq_n_register_fail; } chip->idev = input_allocate_device(); if (!chip->idev) { SENSOR_LOG_ERROR("no memory for idev\n"); ret = -ENODEV; goto input_alloc_failed; } chip->idev->name = "hall_device"; chip->idev->id.bustype = BUS_I2C; set_bit(EV_REL, chip->idev->evbit); set_bit(REL_RX, chip->idev->relbit); //NEAR set_bit(REL_RY, chip->idev->relbit); //FAR ret = input_register_device(chip->idev); if (ret) { input_free_device(chip->idev); SENSOR_LOG_ERROR("cant register input '%s'\n",chip->idev->name); goto input_register_failed; } create_sysfs_interfaces(chip->hall_device_dev); hall_device_irq_enable(&(chip->irq_s), false, true); hall_device_irq_enable(&(chip->irq_n), false, true); wake_lock_init(&chip->wakeup_wakelock.lock, WAKE_LOCK_SUSPEND, chip->wakeup_wakelock.name); hrtimer_init(&chip->unlock_wakelock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); chip->unlock_wakelock_timer.function = hall_device_unlock_wakelock_work_func; SENSOR_LOG_INFO("prob success\n"); return 0; input_register_failed: input_free_device(chip->idev); input_alloc_failed: malloc_failed: irq_n_register_fail: irq_s_register_fail: create_hall_device_dev_failed: chip->hall_device_dev = NULL; class_destroy(hall_device_class); SENSOR_LOG_INFO("prob failed\n"); return -1; }