Loading Documentation/devicetree/bindings/input/misc/bma2x2.txt 0 → 100644 +51 −0 Original line number Diff line number Diff line BOSCH bma2x2 3-axis accelerometer sensor driver. Required properties: - compatible : Should be "bosch,bma2x2". - reg : i2c slave address of the device. - pinctrl-names : Pinctrl configuration names of this sensor driver. Should be "default". - pinctrl-0 : The pinctrl node corresponding to "default", should be <&bma2x2_int1_default &bma2x2_int2_default>. - interrupt-parent : Parent of interrupt. - interrupts : Accelerometer interrupts to indicate new data ready or events. - vdd-supply : Analog power supply needed to power device. - vio-supply : Digital IO power supply needed for IO and I2C. - bosch,init-interval : Initial data polling interval in millisecond. - bosch,place : The placing of the accelerometer on board. There are 8 patterns of placing described as below: 0: 1st pin is right down 1: 1st pin is left down 2: 1st pin is left top 3: 1st pin is right top 4: 1st pin is left down (from top view) 5: 1st pin is left top (from top view) 6: 1st pin is right top (from top view) 7: 1st pin is right down (from top view) Optional properties: - bosch,gpio-int1 : 1st irq gpio which is to provide interrupts to host, interrupt events can be route to any of these two irq pins according device configuration. - bosch,gpio-int2 : 2nd irq gpio which is to provide interrupts to host. Example: &i2c_0 { /* BLSP1 QUP2 */ bosch@18 { /* Accelerometer sensor */ compatible = "bosch,bma2x2"; reg = <0x18>; pinctrl-names = "default"; pinctrl-0 = <&bma2x2_int1_default &bma2x2_int2_default>; interrupt-parent = <&msm_gpio>; interrupts = <112 0x2002>; vdd-supply = <&pm8916_l17>; vio-supply = <&pm8916_l6>; bosch,init-interval = <200>; bosch,place = <1>; bosch,gpio-int1 = <&msm_gpio 112 0x2002>; bosch,gpio-int2 = <&msm_gpio 114 0x2002>; }; }; No newline at end of file drivers/input/misc/bma2x2.c +299 −121 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include <linux/delay.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <linux/regulator/consumer.h> #include <linux/of_gpio.h> #ifdef CONFIG_HAS_EARLYSUSPEND #include <linux/earlysuspend.h> Loading Loading @@ -1357,6 +1359,11 @@ static const struct interrupt_map_t int_map[] = { #endif/*End of CONFIG_SENSORS_BMI058*/ /*BMA power supply VDD 1.62V-3.6V VIO 1.2-3.6V */ #define BMA2x2_VDD_MIN_UV 2000000 #define BMA2x2_VDD_MAX_UV 3400000 #define BMA2x2_VIO_MIN_UV 1500000 #define BMA2x2_VIO_MAX_UV 3400000 struct bma2x2_type_map_t { Loading @@ -1380,19 +1387,6 @@ static const struct bma2x2_type_map_t sensor_type_map[] = { }; /*! * Bst sensor common definition, * please give parameters in BSP file. */ struct bosch_sensor_specific { char *name; /* 0 to 7 */ unsigned int place:3; int irq; int (*irq_gpio_cfg)(void); }; /*! * we use a typedef to hide the detail, * because this type might be changed Loading Loading @@ -1431,6 +1425,14 @@ struct bma2x2acc { s16 z; }; struct bma2x2_platform_data { int poll_interval; int gpio_int1; int gpio_int2; u8 place; bool use_int; }; struct bma2x2_data { struct i2c_client *bma2x2_client; atomic_t delay; Loading @@ -1451,11 +1453,14 @@ struct bma2x2_data { struct mutex mode_mutex; struct delayed_work work; struct work_struct irq_work; struct regulator *vdd; struct regulator *vio; bool power_enabled; #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend; #endif int IRQ; struct bosch_sensor_specific *bst_pd; struct bma2x2_platform_data *pdata; int ref_count; struct input_dev *dev_interrupt; Loading Loading @@ -1537,11 +1542,6 @@ static void bma2x2_remap_sensor_data(struct bma2x2acc *val, { struct bosch_sensor_data bsd; if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) return; #ifdef CONFIG_SENSORS_BMI058 /*x,y need to be invesed becase of HW Register for BMI058*/ bsd.y = val->x; Loading @@ -1554,7 +1554,7 @@ static void bma2x2_remap_sensor_data(struct bma2x2acc *val, #endif bst_remap_sensor_data_dft_tab(&bsd, client_data->bst_pd->place); client_data->pdata->place); val->x = bsd.x; val->y = bsd.y; Loading Loading @@ -5002,8 +5002,7 @@ static ssize_t bma2x2_place_show(struct device *dev, struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); int place = BOSCH_SENSOR_PLACE_UNKNOWN; if (NULL != bma2x2->bst_pd) place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; return snprintf(buf, PAGE_SIZE, "%d\n", place); } Loading Loading @@ -5437,9 +5436,7 @@ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, #endif /*remaping fifo_dat_sel if define virtual place in BSP files*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /* BMA2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3; Loading @@ -5450,7 +5447,6 @@ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } return snprintf(buf, PAGE_SIZE, "%d\n", data); Loading Loading @@ -5525,9 +5521,7 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, bma2x2->fifo_datasel = (unsigned char) data; /*remaping fifo_dat_sel if define virtual place*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /*Need X Y axis revesal sensor place: P1, P3, P5, P7 */ Loading @@ -5539,7 +5533,6 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } #ifdef CONFIG_SENSORS_BMI058 /*Update BMI058 fifo_data_sel to the BMA2x2 common definition*/ if (BMA2X2_FIFO_DAT_SEL_X == data) Loading Loading @@ -5567,19 +5560,14 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, static void bma2x2_single_axis_remaping(unsigned char fifo_datasel, unsigned char *remap_dir, struct bma2x2_data *client_data) { if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) return; else { signed char place = client_data->bst_pd->place; signed char place = client_data->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ)) return; if (fifo_datasel < 1 || fifo_datasel > 3) return; else { switch (fifo_datasel) { /*P2, P3, P4, P5 X axis(andorid) need to reverse*/ case BMA2X2_FIFO_DAT_SEL_X: Loading @@ -5605,8 +5593,7 @@ static void bma2x2_single_axis_remaping(unsigned char fifo_datasel, default: break; } } } return; } Loading Loading @@ -6515,6 +6502,168 @@ static irqreturn_t bma2x2_irq_handler(int irq, void *handle) } #endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */ static int bma2x2_power_ctl(struct bma2x2_data *data, bool on) { int ret = 0; int err = 0; if (!on && data->power_enabled) { ret = regulator_disable(data->vdd); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vdd disable failed ret=%d\n", ret); return ret; } ret = regulator_disable(data->vio); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vio disable failed ret=%d\n", ret); err = regulator_enable(data->vdd); return ret; } data->power_enabled = on; } else if (on && !data->power_enabled) { ret = regulator_enable(data->vdd); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vdd enable failed ret=%d\n", ret); return ret; } ret = regulator_enable(data->vio); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vio enable failed ret=%d\n", ret); err = regulator_disable(data->vdd); return ret; } data->power_enabled = on; } else { dev_info(&data->bma2x2_client->dev, "Power on=%d. enabled=%d\n", on, data->power_enabled); } return ret; } static int bma2x2_power_init(struct bma2x2_data *data) { int ret; data->vdd = regulator_get(&data->bma2x2_client->dev, "vdd"); if (IS_ERR(data->vdd)) { ret = PTR_ERR(data->vdd); dev_err(&data->bma2x2_client->dev, "Regulator get failed vdd ret=%d\n", ret); return ret; } if (regulator_count_voltages(data->vdd) > 0) { ret = regulator_set_voltage(data->vdd, BMA2x2_VDD_MIN_UV, BMA2x2_VDD_MAX_UV); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator set failed vdd ret=%d\n", ret); goto reg_vdd_put; } } data->vio = regulator_get(&data->bma2x2_client->dev, "vio"); if (IS_ERR(data->vio)) { ret = PTR_ERR(data->vio); dev_err(&data->bma2x2_client->dev, "Regulator get failed vio ret=%d\n", ret); goto reg_vdd_set; } if (regulator_count_voltages(data->vio) > 0) { ret = regulator_set_voltage(data->vio, BMA2x2_VIO_MIN_UV, BMA2x2_VIO_MAX_UV); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator set failed vio ret=%d\n", ret); goto reg_vio_put; } } return 0; reg_vio_put: regulator_put(data->vio); reg_vdd_set: if (regulator_count_voltages(data->vdd) > 0) regulator_set_voltage(data->vdd, 0, BMA2x2_VDD_MAX_UV); reg_vdd_put: regulator_put(data->vdd); return ret; } static int bma2x2_power_deinit(struct bma2x2_data *data) { if (regulator_count_voltages(data->vdd) > 0) regulator_set_voltage(data->vdd, 0, BMA2x2_VDD_MAX_UV); regulator_put(data->vdd); if (regulator_count_voltages(data->vio) > 0) regulator_set_voltage(data->vio, 0, BMA2x2_VIO_MAX_UV); regulator_put(data->vio); return 0; } #ifdef CONFIG_OF static int bma2x2_parse_dt(struct device *dev, struct bma2x2_platform_data *pdata) { struct device_node *np = dev->of_node; u32 temp_val; int rc; rc = of_property_read_u32(np, "bosch,init-interval", &temp_val); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read init-interval\n"); return rc; } else { pdata->poll_interval = temp_val; } rc = of_property_read_u32(np, "bosch,place", &temp_val); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read sensor place paramater\n"); return rc; } if (temp_val > 7 || temp_val < 0) { dev_err(dev, "Invalid place parameter, use default value 0\n"); pdata->place = 0; } else { pdata->place = temp_val; } pdata->use_int = of_property_read_bool(np, "bosch,use-interrupt"); pdata->gpio_int1 = of_get_named_gpio_flags(dev->of_node, "bosch,gpio-int1", 0, NULL); pdata->gpio_int2 = of_get_named_gpio_flags(dev->of_node, "bosch,gpio-int2", 0, NULL); return 0; } #else static int bma2x2_parse_dt(struct device *dev, struct bma2x2_platform_data *pdata) { return -EINVAL; } #endif static int bma2x2_probe(struct i2c_client *client, const struct i2c_device_id *id) Loading @@ -6523,10 +6672,7 @@ static int bma2x2_probe(struct i2c_client *client, struct bma2x2_data *data; struct input_dev *dev; struct bst_dev *dev_acc; #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) struct bosch_sensor_specific *pdata; #endif struct bma2x2_platform_data *pdata; struct input_dev *dev_interrupt; Loading @@ -6540,6 +6686,46 @@ static int bma2x2_probe(struct i2c_client *client, err = -ENOMEM; goto exit; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "Failed to allcated memory\n"); err = -ENOMEM; goto kfree_exit; } err = bma2x2_parse_dt(&client->dev, pdata); if (err) { dev_err(&client->dev, "Failed to parse device tree\n"); err = -EINVAL; goto pdata_free_exit; } } else { pdata = client->dev.platform_data; dev_err(&client->dev, "use platform data\n"); } if (!pdata) { dev_err(&client->dev, "Cannot get device platform data\n"); err = -EINVAL; goto kfree_exit; } data->pdata = pdata; i2c_set_clientdata(client, data); data->bma2x2_client = client; err = bma2x2_power_init(data); if (err) { dev_err(&client->dev, "Failed to get sensor regulators\n"); err = -EINVAL; goto free_i2c_clientdata_exit; } err = bma2x2_power_ctl(data, true); if (err) { dev_err(&client->dev, "Failed to enable sensor power\n"); err = -EINVAL; goto deinit_power_exit; } /* do soft reset */ RESET_DELAY(); Loading @@ -6547,17 +6733,15 @@ static int bma2x2_probe(struct i2c_client *client, dev_err(&client->dev, "i2c bus write error, pls check HW connection\n"); err = -EINVAL; goto kfree_exit; goto disable_power_exit; } RESET_DELAY(); /* read and check chip id */ if (bma2x2_check_chip_id(client, data) < 0) { err = -EINVAL; goto kfree_exit; goto disable_power_exit; } i2c_set_clientdata(client, data); data->bma2x2_client = client; mutex_init(&data->value_mutex); mutex_init(&data->mode_mutex); mutex_init(&data->enable_mutex); Loading Loading @@ -6771,19 +6955,6 @@ static int bma2x2_probe(struct i2c_client *client, if (err < 0) goto bst_free_exit; if (NULL != client->dev.platform_data) { data->bst_pd = kzalloc(sizeof(*data->bst_pd), GFP_KERNEL); if (NULL != data->bst_pd) { memcpy(data->bst_pd, client->dev.platform_data, sizeof(*data->bst_pd)); dev_notice(&client->dev, "%s sensor driver set place: p%d", data->bst_pd->name, data->bst_pd->place); } } #ifdef CONFIG_HAS_EARLYSUSPEND data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = bma2x2_early_suspend; Loading Loading @@ -6841,11 +7012,17 @@ err_register_input_device_interrupt: err_register_input_device: input_free_device(dev); disable_power_exit: bma2x2_power_ctl(data, false); deinit_power_exit: bma2x2_power_deinit(data); free_i2c_clientdata_exit: i2c_set_clientdata(client, NULL); pdata_free_exit: if (pdata && (client->dev.of_node)) devm_kfree(&client->dev, pdata); data->pdata = NULL; kfree_exit: if ((NULL != data) && (NULL != data->bst_pd)) { kfree(data->bst_pd); data->bst_pd = NULL; } kfree(data); exit: return err; Loading Loading @@ -6895,11 +7072,6 @@ static int bma2x2_remove(struct i2c_client *client) sysfs_remove_group(&data->input->dev.kobj, &bma2x2_attribute_group); input_unregister_device(data->input); if ((NULL != data) && (NULL != data->bst_pd)) { kfree(data->bst_pd); data->bst_pd = NULL; } kfree(data); return 0; Loading Loading @@ -6962,10 +7134,16 @@ static const struct i2c_device_id bma2x2_id[] = { MODULE_DEVICE_TABLE(i2c, bma2x2_id); static const struct of_device_id bma2x2_of_match[] = { { .compatible = "bosch,bma2x2", }, { }, }; static struct i2c_driver bma2x2_driver = { .driver = { .owner = THIS_MODULE, .name = SENSOR_NAME, .of_match_table = bma2x2_of_match, }, .suspend = bma2x2_suspend, .resume = bma2x2_resume, Loading Loading
Documentation/devicetree/bindings/input/misc/bma2x2.txt 0 → 100644 +51 −0 Original line number Diff line number Diff line BOSCH bma2x2 3-axis accelerometer sensor driver. Required properties: - compatible : Should be "bosch,bma2x2". - reg : i2c slave address of the device. - pinctrl-names : Pinctrl configuration names of this sensor driver. Should be "default". - pinctrl-0 : The pinctrl node corresponding to "default", should be <&bma2x2_int1_default &bma2x2_int2_default>. - interrupt-parent : Parent of interrupt. - interrupts : Accelerometer interrupts to indicate new data ready or events. - vdd-supply : Analog power supply needed to power device. - vio-supply : Digital IO power supply needed for IO and I2C. - bosch,init-interval : Initial data polling interval in millisecond. - bosch,place : The placing of the accelerometer on board. There are 8 patterns of placing described as below: 0: 1st pin is right down 1: 1st pin is left down 2: 1st pin is left top 3: 1st pin is right top 4: 1st pin is left down (from top view) 5: 1st pin is left top (from top view) 6: 1st pin is right top (from top view) 7: 1st pin is right down (from top view) Optional properties: - bosch,gpio-int1 : 1st irq gpio which is to provide interrupts to host, interrupt events can be route to any of these two irq pins according device configuration. - bosch,gpio-int2 : 2nd irq gpio which is to provide interrupts to host. Example: &i2c_0 { /* BLSP1 QUP2 */ bosch@18 { /* Accelerometer sensor */ compatible = "bosch,bma2x2"; reg = <0x18>; pinctrl-names = "default"; pinctrl-0 = <&bma2x2_int1_default &bma2x2_int2_default>; interrupt-parent = <&msm_gpio>; interrupts = <112 0x2002>; vdd-supply = <&pm8916_l17>; vio-supply = <&pm8916_l6>; bosch,init-interval = <200>; bosch,place = <1>; bosch,gpio-int1 = <&msm_gpio 112 0x2002>; bosch,gpio-int2 = <&msm_gpio 114 0x2002>; }; }; No newline at end of file
drivers/input/misc/bma2x2.c +299 −121 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include <linux/delay.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <linux/regulator/consumer.h> #include <linux/of_gpio.h> #ifdef CONFIG_HAS_EARLYSUSPEND #include <linux/earlysuspend.h> Loading Loading @@ -1357,6 +1359,11 @@ static const struct interrupt_map_t int_map[] = { #endif/*End of CONFIG_SENSORS_BMI058*/ /*BMA power supply VDD 1.62V-3.6V VIO 1.2-3.6V */ #define BMA2x2_VDD_MIN_UV 2000000 #define BMA2x2_VDD_MAX_UV 3400000 #define BMA2x2_VIO_MIN_UV 1500000 #define BMA2x2_VIO_MAX_UV 3400000 struct bma2x2_type_map_t { Loading @@ -1380,19 +1387,6 @@ static const struct bma2x2_type_map_t sensor_type_map[] = { }; /*! * Bst sensor common definition, * please give parameters in BSP file. */ struct bosch_sensor_specific { char *name; /* 0 to 7 */ unsigned int place:3; int irq; int (*irq_gpio_cfg)(void); }; /*! * we use a typedef to hide the detail, * because this type might be changed Loading Loading @@ -1431,6 +1425,14 @@ struct bma2x2acc { s16 z; }; struct bma2x2_platform_data { int poll_interval; int gpio_int1; int gpio_int2; u8 place; bool use_int; }; struct bma2x2_data { struct i2c_client *bma2x2_client; atomic_t delay; Loading @@ -1451,11 +1453,14 @@ struct bma2x2_data { struct mutex mode_mutex; struct delayed_work work; struct work_struct irq_work; struct regulator *vdd; struct regulator *vio; bool power_enabled; #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend; #endif int IRQ; struct bosch_sensor_specific *bst_pd; struct bma2x2_platform_data *pdata; int ref_count; struct input_dev *dev_interrupt; Loading Loading @@ -1537,11 +1542,6 @@ static void bma2x2_remap_sensor_data(struct bma2x2acc *val, { struct bosch_sensor_data bsd; if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) return; #ifdef CONFIG_SENSORS_BMI058 /*x,y need to be invesed becase of HW Register for BMI058*/ bsd.y = val->x; Loading @@ -1554,7 +1554,7 @@ static void bma2x2_remap_sensor_data(struct bma2x2acc *val, #endif bst_remap_sensor_data_dft_tab(&bsd, client_data->bst_pd->place); client_data->pdata->place); val->x = bsd.x; val->y = bsd.y; Loading Loading @@ -5002,8 +5002,7 @@ static ssize_t bma2x2_place_show(struct device *dev, struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); int place = BOSCH_SENSOR_PLACE_UNKNOWN; if (NULL != bma2x2->bst_pd) place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; return snprintf(buf, PAGE_SIZE, "%d\n", place); } Loading Loading @@ -5437,9 +5436,7 @@ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, #endif /*remaping fifo_dat_sel if define virtual place in BSP files*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /* BMA2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3; Loading @@ -5450,7 +5447,6 @@ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } return snprintf(buf, PAGE_SIZE, "%d\n", data); Loading Loading @@ -5525,9 +5521,7 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, bma2x2->fifo_datasel = (unsigned char) data; /*remaping fifo_dat_sel if define virtual place*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; place = bma2x2->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /*Need X Y axis revesal sensor place: P1, P3, P5, P7 */ Loading @@ -5539,7 +5533,6 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } #ifdef CONFIG_SENSORS_BMI058 /*Update BMI058 fifo_data_sel to the BMA2x2 common definition*/ if (BMA2X2_FIFO_DAT_SEL_X == data) Loading Loading @@ -5567,19 +5560,14 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, static void bma2x2_single_axis_remaping(unsigned char fifo_datasel, unsigned char *remap_dir, struct bma2x2_data *client_data) { if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) return; else { signed char place = client_data->bst_pd->place; signed char place = client_data->pdata->place; /* sensor with place 0 needs not to be remapped */ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ)) return; if (fifo_datasel < 1 || fifo_datasel > 3) return; else { switch (fifo_datasel) { /*P2, P3, P4, P5 X axis(andorid) need to reverse*/ case BMA2X2_FIFO_DAT_SEL_X: Loading @@ -5605,8 +5593,7 @@ static void bma2x2_single_axis_remaping(unsigned char fifo_datasel, default: break; } } } return; } Loading Loading @@ -6515,6 +6502,168 @@ static irqreturn_t bma2x2_irq_handler(int irq, void *handle) } #endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */ static int bma2x2_power_ctl(struct bma2x2_data *data, bool on) { int ret = 0; int err = 0; if (!on && data->power_enabled) { ret = regulator_disable(data->vdd); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vdd disable failed ret=%d\n", ret); return ret; } ret = regulator_disable(data->vio); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vio disable failed ret=%d\n", ret); err = regulator_enable(data->vdd); return ret; } data->power_enabled = on; } else if (on && !data->power_enabled) { ret = regulator_enable(data->vdd); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vdd enable failed ret=%d\n", ret); return ret; } ret = regulator_enable(data->vio); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator vio enable failed ret=%d\n", ret); err = regulator_disable(data->vdd); return ret; } data->power_enabled = on; } else { dev_info(&data->bma2x2_client->dev, "Power on=%d. enabled=%d\n", on, data->power_enabled); } return ret; } static int bma2x2_power_init(struct bma2x2_data *data) { int ret; data->vdd = regulator_get(&data->bma2x2_client->dev, "vdd"); if (IS_ERR(data->vdd)) { ret = PTR_ERR(data->vdd); dev_err(&data->bma2x2_client->dev, "Regulator get failed vdd ret=%d\n", ret); return ret; } if (regulator_count_voltages(data->vdd) > 0) { ret = regulator_set_voltage(data->vdd, BMA2x2_VDD_MIN_UV, BMA2x2_VDD_MAX_UV); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator set failed vdd ret=%d\n", ret); goto reg_vdd_put; } } data->vio = regulator_get(&data->bma2x2_client->dev, "vio"); if (IS_ERR(data->vio)) { ret = PTR_ERR(data->vio); dev_err(&data->bma2x2_client->dev, "Regulator get failed vio ret=%d\n", ret); goto reg_vdd_set; } if (regulator_count_voltages(data->vio) > 0) { ret = regulator_set_voltage(data->vio, BMA2x2_VIO_MIN_UV, BMA2x2_VIO_MAX_UV); if (ret) { dev_err(&data->bma2x2_client->dev, "Regulator set failed vio ret=%d\n", ret); goto reg_vio_put; } } return 0; reg_vio_put: regulator_put(data->vio); reg_vdd_set: if (regulator_count_voltages(data->vdd) > 0) regulator_set_voltage(data->vdd, 0, BMA2x2_VDD_MAX_UV); reg_vdd_put: regulator_put(data->vdd); return ret; } static int bma2x2_power_deinit(struct bma2x2_data *data) { if (regulator_count_voltages(data->vdd) > 0) regulator_set_voltage(data->vdd, 0, BMA2x2_VDD_MAX_UV); regulator_put(data->vdd); if (regulator_count_voltages(data->vio) > 0) regulator_set_voltage(data->vio, 0, BMA2x2_VIO_MAX_UV); regulator_put(data->vio); return 0; } #ifdef CONFIG_OF static int bma2x2_parse_dt(struct device *dev, struct bma2x2_platform_data *pdata) { struct device_node *np = dev->of_node; u32 temp_val; int rc; rc = of_property_read_u32(np, "bosch,init-interval", &temp_val); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read init-interval\n"); return rc; } else { pdata->poll_interval = temp_val; } rc = of_property_read_u32(np, "bosch,place", &temp_val); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read sensor place paramater\n"); return rc; } if (temp_val > 7 || temp_val < 0) { dev_err(dev, "Invalid place parameter, use default value 0\n"); pdata->place = 0; } else { pdata->place = temp_val; } pdata->use_int = of_property_read_bool(np, "bosch,use-interrupt"); pdata->gpio_int1 = of_get_named_gpio_flags(dev->of_node, "bosch,gpio-int1", 0, NULL); pdata->gpio_int2 = of_get_named_gpio_flags(dev->of_node, "bosch,gpio-int2", 0, NULL); return 0; } #else static int bma2x2_parse_dt(struct device *dev, struct bma2x2_platform_data *pdata) { return -EINVAL; } #endif static int bma2x2_probe(struct i2c_client *client, const struct i2c_device_id *id) Loading @@ -6523,10 +6672,7 @@ static int bma2x2_probe(struct i2c_client *client, struct bma2x2_data *data; struct input_dev *dev; struct bst_dev *dev_acc; #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) struct bosch_sensor_specific *pdata; #endif struct bma2x2_platform_data *pdata; struct input_dev *dev_interrupt; Loading @@ -6540,6 +6686,46 @@ static int bma2x2_probe(struct i2c_client *client, err = -ENOMEM; goto exit; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "Failed to allcated memory\n"); err = -ENOMEM; goto kfree_exit; } err = bma2x2_parse_dt(&client->dev, pdata); if (err) { dev_err(&client->dev, "Failed to parse device tree\n"); err = -EINVAL; goto pdata_free_exit; } } else { pdata = client->dev.platform_data; dev_err(&client->dev, "use platform data\n"); } if (!pdata) { dev_err(&client->dev, "Cannot get device platform data\n"); err = -EINVAL; goto kfree_exit; } data->pdata = pdata; i2c_set_clientdata(client, data); data->bma2x2_client = client; err = bma2x2_power_init(data); if (err) { dev_err(&client->dev, "Failed to get sensor regulators\n"); err = -EINVAL; goto free_i2c_clientdata_exit; } err = bma2x2_power_ctl(data, true); if (err) { dev_err(&client->dev, "Failed to enable sensor power\n"); err = -EINVAL; goto deinit_power_exit; } /* do soft reset */ RESET_DELAY(); Loading @@ -6547,17 +6733,15 @@ static int bma2x2_probe(struct i2c_client *client, dev_err(&client->dev, "i2c bus write error, pls check HW connection\n"); err = -EINVAL; goto kfree_exit; goto disable_power_exit; } RESET_DELAY(); /* read and check chip id */ if (bma2x2_check_chip_id(client, data) < 0) { err = -EINVAL; goto kfree_exit; goto disable_power_exit; } i2c_set_clientdata(client, data); data->bma2x2_client = client; mutex_init(&data->value_mutex); mutex_init(&data->mode_mutex); mutex_init(&data->enable_mutex); Loading Loading @@ -6771,19 +6955,6 @@ static int bma2x2_probe(struct i2c_client *client, if (err < 0) goto bst_free_exit; if (NULL != client->dev.platform_data) { data->bst_pd = kzalloc(sizeof(*data->bst_pd), GFP_KERNEL); if (NULL != data->bst_pd) { memcpy(data->bst_pd, client->dev.platform_data, sizeof(*data->bst_pd)); dev_notice(&client->dev, "%s sensor driver set place: p%d", data->bst_pd->name, data->bst_pd->place); } } #ifdef CONFIG_HAS_EARLYSUSPEND data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = bma2x2_early_suspend; Loading Loading @@ -6841,11 +7012,17 @@ err_register_input_device_interrupt: err_register_input_device: input_free_device(dev); disable_power_exit: bma2x2_power_ctl(data, false); deinit_power_exit: bma2x2_power_deinit(data); free_i2c_clientdata_exit: i2c_set_clientdata(client, NULL); pdata_free_exit: if (pdata && (client->dev.of_node)) devm_kfree(&client->dev, pdata); data->pdata = NULL; kfree_exit: if ((NULL != data) && (NULL != data->bst_pd)) { kfree(data->bst_pd); data->bst_pd = NULL; } kfree(data); exit: return err; Loading Loading @@ -6895,11 +7072,6 @@ static int bma2x2_remove(struct i2c_client *client) sysfs_remove_group(&data->input->dev.kobj, &bma2x2_attribute_group); input_unregister_device(data->input); if ((NULL != data) && (NULL != data->bst_pd)) { kfree(data->bst_pd); data->bst_pd = NULL; } kfree(data); return 0; Loading Loading @@ -6962,10 +7134,16 @@ static const struct i2c_device_id bma2x2_id[] = { MODULE_DEVICE_TABLE(i2c, bma2x2_id); static const struct of_device_id bma2x2_of_match[] = { { .compatible = "bosch,bma2x2", }, { }, }; static struct i2c_driver bma2x2_driver = { .driver = { .owner = THIS_MODULE, .name = SENSOR_NAME, .of_match_table = bma2x2_of_match, }, .suspend = bma2x2_suspend, .resume = bma2x2_resume, Loading