diff options
| -rw-r--r-- | Documentation/devicetree/bindings/misc/lis302.txt | 76 | ||||
| -rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.c | 153 | ||||
| -rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.h | 4 |
3 files changed, 233 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/misc/lis302.txt b/Documentation/devicetree/bindings/misc/lis302.txt new file mode 100644 index 000000000000..e18af9d19793 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/lis302.txt | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | LIS302 accelerometer devicetree bindings | ||
| 2 | |||
| 3 | This device is matched via its bus drivers, and has a number of properties | ||
| 4 | that apply in on the generic device (independent from the bus). | ||
| 5 | |||
| 6 | |||
| 7 | Required properties for the SPI bindings: | ||
| 8 | - compatible: should be set to "st,lis3lv02d_spi" | ||
| 9 | - reg: the chipselect index | ||
| 10 | - spi-max-frequency: maximal bus speed, should be set to 1000000 unless | ||
| 11 | constrained by external circuitry | ||
| 12 | - interrupts: the interrupt generated by the device | ||
| 13 | |||
| 14 | |||
| 15 | Optional properties for all bus drivers: | ||
| 16 | |||
| 17 | - st,click-single-{x,y,z}: if present, tells the device to issue an | ||
| 18 | interrupt on single click events on the | ||
| 19 | x/y/z axis. | ||
| 20 | - st,click-double-{x,y,z}: if present, tells the device to issue an | ||
| 21 | interrupt on double click events on the | ||
| 22 | x/y/z axis. | ||
| 23 | - st,click-thresh-{x,y,z}: set the x/y/z axis threshold | ||
| 24 | - st,click-click-time-limit: click time limit, from 0 to 127.5msec | ||
| 25 | with step of 0.5 msec | ||
| 26 | - st,click-latency: click latency, from 0 to 255 msec with | ||
| 27 | step of 1 msec. | ||
| 28 | - st,click-window: click window, from 0 to 255 msec with | ||
| 29 | step of 1 msec. | ||
| 30 | - st,irq{1,2}-disable: disable IRQ 1/2 | ||
| 31 | - st,irq{1,2}-ff-wu-1: raise IRQ 1/2 on FF_WU_1 condition | ||
| 32 | - st,irq{1,2}-ff-wu-2: raise IRQ 1/2 on FF_WU_2 condition | ||
| 33 | - st,irq{1,2}-data-ready: raise IRQ 1/2 on data ready contition | ||
| 34 | - st,irq{1,2}-click: raise IRQ 1/2 on click condition | ||
| 35 | - st,irq-open-drain: consider IRQ lines open-drain | ||
| 36 | - st,irq-active-low: make IRQ lines active low | ||
| 37 | - st,wu-duration-1: duration register for Free-Fall/Wake-Up | ||
| 38 | interrupt 1 | ||
| 39 | - st,wu-duration-2: duration register for Free-Fall/Wake-Up | ||
| 40 | interrupt 2 | ||
| 41 | - st,wakeup-{x,y,z}-{lo,hi}: set wakeup condition on x/y/z axis for | ||
| 42 | upper/lower limit | ||
| 43 | - st,highpass-cutoff-hz=: 1, 2, 4 or 8 for 1Hz, 2Hz, 4Hz or 8Hz of | ||
| 44 | highpass cut-off frequency | ||
| 45 | - st,hipass{1,2}-disable: disable highpass 1/2. | ||
| 46 | - st,default-rate=: set the default rate | ||
| 47 | - st,axis-{x,y,z}=: set the axis to map to the three coordinates | ||
| 48 | - st,{min,max}-limit-{x,y,z} set the min/max limits for x/y/z axis | ||
| 49 | (used by self-test) | ||
| 50 | |||
| 51 | |||
| 52 | Example for a SPI device node: | ||
| 53 | |||
| 54 | lis302@0 { | ||
| 55 | compatible = "st,lis302dl-spi"; | ||
| 56 | reg = <0>; | ||
| 57 | spi-max-frequency = <1000000>; | ||
| 58 | interrupt-parent = <&gpio>; | ||
| 59 | interrupts = <104 0>; | ||
| 60 | |||
| 61 | st,click-single-x; | ||
| 62 | st,click-single-y; | ||
| 63 | st,click-single-z; | ||
| 64 | st,click-thresh-x = <10>; | ||
| 65 | st,click-thresh-y = <10>; | ||
| 66 | st,click-thresh-z = <10>; | ||
| 67 | st,irq1-click; | ||
| 68 | st,irq2-click; | ||
| 69 | st,wakeup-x-lo; | ||
| 70 | st,wakeup-x-hi; | ||
| 71 | st,wakeup-y-lo; | ||
| 72 | st,wakeup-y-hi; | ||
| 73 | st,wakeup-z-lo; | ||
| 74 | st,wakeup-z-hi; | ||
| 75 | }; | ||
| 76 | |||
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index e670072fe24c..6877f1179875 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
| 40 | #include <linux/pm_runtime.h> | 40 | #include <linux/pm_runtime.h> |
| 41 | #include <linux/atomic.h> | 41 | #include <linux/atomic.h> |
| 42 | #include <linux/of_device.h> | ||
| 42 | #include "lis3lv02d.h" | 43 | #include "lis3lv02d.h" |
| 43 | 44 | ||
| 44 | #define DRIVER_NAME "lis3lv02d" | 45 | #define DRIVER_NAME "lis3lv02d" |
| @@ -943,6 +944,154 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3, | |||
| 943 | } | 944 | } |
| 944 | } | 945 | } |
| 945 | 946 | ||
| 947 | #ifdef CONFIG_OF | ||
| 948 | static int lis3lv02d_init_dt(struct lis3lv02d *lis3) | ||
| 949 | { | ||
| 950 | struct lis3lv02d_platform_data *pdata; | ||
| 951 | struct device_node *np = lis3->of_node; | ||
| 952 | u32 val; | ||
| 953 | |||
| 954 | if (!lis3->of_node) | ||
| 955 | return 0; | ||
| 956 | |||
| 957 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
| 958 | if (!pdata) | ||
| 959 | return -ENOMEM; | ||
| 960 | |||
| 961 | if (of_get_property(np, "st,click-single-x", NULL)) | ||
| 962 | pdata->click_flags |= LIS3_CLICK_SINGLE_X; | ||
| 963 | if (of_get_property(np, "st,click-double-x", NULL)) | ||
| 964 | pdata->click_flags |= LIS3_CLICK_DOUBLE_X; | ||
| 965 | |||
| 966 | if (of_get_property(np, "st,click-single-y", NULL)) | ||
| 967 | pdata->click_flags |= LIS3_CLICK_SINGLE_Y; | ||
| 968 | if (of_get_property(np, "st,click-double-y", NULL)) | ||
| 969 | pdata->click_flags |= LIS3_CLICK_DOUBLE_Y; | ||
| 970 | |||
| 971 | if (of_get_property(np, "st,click-single-z", NULL)) | ||
| 972 | pdata->click_flags |= LIS3_CLICK_SINGLE_Z; | ||
| 973 | if (of_get_property(np, "st,click-double-z", NULL)) | ||
| 974 | pdata->click_flags |= LIS3_CLICK_DOUBLE_Z; | ||
| 975 | |||
| 976 | if (!of_property_read_u32(np, "st,click-threshold-x", &val)) | ||
| 977 | pdata->click_thresh_x = val; | ||
| 978 | if (!of_property_read_u32(np, "st,click-threshold-y", &val)) | ||
| 979 | pdata->click_thresh_y = val; | ||
| 980 | if (!of_property_read_u32(np, "st,click-threshold-z", &val)) | ||
| 981 | pdata->click_thresh_z = val; | ||
| 982 | |||
| 983 | if (!of_property_read_u32(np, "st,click-time-limit", &val)) | ||
| 984 | pdata->click_time_limit = val; | ||
| 985 | if (!of_property_read_u32(np, "st,click-latency", &val)) | ||
| 986 | pdata->click_latency = val; | ||
| 987 | if (!of_property_read_u32(np, "st,click-window", &val)) | ||
| 988 | pdata->click_window = val; | ||
| 989 | |||
| 990 | if (of_get_property(np, "st,irq1-disable", NULL)) | ||
| 991 | pdata->irq_cfg |= LIS3_IRQ1_DISABLE; | ||
| 992 | if (of_get_property(np, "st,irq1-ff-wu-1", NULL)) | ||
| 993 | pdata->irq_cfg |= LIS3_IRQ1_FF_WU_1; | ||
| 994 | if (of_get_property(np, "st,irq1-ff-wu-2", NULL)) | ||
| 995 | pdata->irq_cfg |= LIS3_IRQ1_FF_WU_2; | ||
| 996 | if (of_get_property(np, "st,irq1-data-ready", NULL)) | ||
| 997 | pdata->irq_cfg |= LIS3_IRQ1_DATA_READY; | ||
| 998 | if (of_get_property(np, "st,irq1-click", NULL)) | ||
| 999 | pdata->irq_cfg |= LIS3_IRQ1_CLICK; | ||
| 1000 | |||
| 1001 | if (of_get_property(np, "st,irq2-disable", NULL)) | ||
| 1002 | pdata->irq_cfg |= LIS3_IRQ2_DISABLE; | ||
| 1003 | if (of_get_property(np, "st,irq2-ff-wu-1", NULL)) | ||
| 1004 | pdata->irq_cfg |= LIS3_IRQ2_FF_WU_1; | ||
| 1005 | if (of_get_property(np, "st,irq2-ff-wu-2", NULL)) | ||
| 1006 | pdata->irq_cfg |= LIS3_IRQ2_FF_WU_2; | ||
| 1007 | if (of_get_property(np, "st,irq2-data-ready", NULL)) | ||
| 1008 | pdata->irq_cfg |= LIS3_IRQ2_DATA_READY; | ||
| 1009 | if (of_get_property(np, "st,irq2-click", NULL)) | ||
| 1010 | pdata->irq_cfg |= LIS3_IRQ2_CLICK; | ||
| 1011 | |||
| 1012 | if (of_get_property(np, "st,irq-open-drain", NULL)) | ||
| 1013 | pdata->irq_cfg |= LIS3_IRQ_OPEN_DRAIN; | ||
| 1014 | if (of_get_property(np, "st,irq-active-low", NULL)) | ||
| 1015 | pdata->irq_cfg |= LIS3_IRQ_ACTIVE_LOW; | ||
| 1016 | |||
| 1017 | if (!of_property_read_u32(np, "st,wu-duration-1", &val)) | ||
| 1018 | pdata->duration1 = val; | ||
| 1019 | if (!of_property_read_u32(np, "st,wu-duration-2", &val)) | ||
| 1020 | pdata->duration2 = val; | ||
| 1021 | |||
| 1022 | if (of_get_property(np, "st,wakeup-x-lo", NULL)) | ||
| 1023 | pdata->wakeup_flags |= LIS3_WAKEUP_X_LO; | ||
| 1024 | if (of_get_property(np, "st,wakeup-x-hi", NULL)) | ||
| 1025 | pdata->wakeup_flags |= LIS3_WAKEUP_X_HI; | ||
| 1026 | if (of_get_property(np, "st,wakeup-y-lo", NULL)) | ||
| 1027 | pdata->wakeup_flags |= LIS3_WAKEUP_Y_LO; | ||
| 1028 | if (of_get_property(np, "st,wakeup-y-hi", NULL)) | ||
| 1029 | pdata->wakeup_flags |= LIS3_WAKEUP_Y_HI; | ||
| 1030 | if (of_get_property(np, "st,wakeup-z-lo", NULL)) | ||
| 1031 | pdata->wakeup_flags |= LIS3_WAKEUP_Z_LO; | ||
| 1032 | if (of_get_property(np, "st,wakeup-z-hi", NULL)) | ||
| 1033 | pdata->wakeup_flags |= LIS3_WAKEUP_Z_HI; | ||
| 1034 | |||
| 1035 | if (!of_property_read_u32(np, "st,highpass-cutoff-hz", &val)) { | ||
| 1036 | switch (val) { | ||
| 1037 | case 1: | ||
| 1038 | pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_1HZ; | ||
| 1039 | break; | ||
| 1040 | case 2: | ||
| 1041 | pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_2HZ; | ||
| 1042 | break; | ||
| 1043 | case 4: | ||
| 1044 | pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_4HZ; | ||
| 1045 | break; | ||
| 1046 | case 8: | ||
| 1047 | pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_8HZ; | ||
| 1048 | break; | ||
| 1049 | } | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | if (of_get_property(np, "st,hipass1-disable", NULL)) | ||
| 1053 | pdata->hipass_ctrl |= LIS3_HIPASS1_DISABLE; | ||
| 1054 | if (of_get_property(np, "st,hipass2-disable", NULL)) | ||
| 1055 | pdata->hipass_ctrl |= LIS3_HIPASS2_DISABLE; | ||
| 1056 | |||
| 1057 | if (of_get_property(np, "st,axis-x", &val)) | ||
| 1058 | pdata->axis_x = val; | ||
| 1059 | if (of_get_property(np, "st,axis-y", &val)) | ||
| 1060 | pdata->axis_y = val; | ||
| 1061 | if (of_get_property(np, "st,axis-z", &val)) | ||
| 1062 | pdata->axis_z = val; | ||
| 1063 | |||
| 1064 | if (of_get_property(np, "st,default-rate", NULL)) | ||
| 1065 | pdata->default_rate = val; | ||
| 1066 | |||
| 1067 | if (of_get_property(np, "st,min-limit-x", &val)) | ||
| 1068 | pdata->st_min_limits[0] = val; | ||
| 1069 | if (of_get_property(np, "st,min-limit-y", &val)) | ||
| 1070 | pdata->st_min_limits[1] = val; | ||
| 1071 | if (of_get_property(np, "st,min-limit-z", &val)) | ||
| 1072 | pdata->st_min_limits[2] = val; | ||
| 1073 | |||
| 1074 | if (of_get_property(np, "st,max-limit-x", &val)) | ||
| 1075 | pdata->st_max_limits[0] = val; | ||
| 1076 | if (of_get_property(np, "st,max-limit-y", &val)) | ||
| 1077 | pdata->st_max_limits[1] = val; | ||
| 1078 | if (of_get_property(np, "st,max-limit-z", &val)) | ||
| 1079 | pdata->st_max_limits[2] = val; | ||
| 1080 | |||
| 1081 | |||
| 1082 | lis3->pdata = pdata; | ||
| 1083 | |||
| 1084 | return 0; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | #else | ||
| 1088 | static int lis3lv02d_init_dt(struct lis3lv02d *lis3) | ||
| 1089 | { | ||
| 1090 | return 0; | ||
| 1091 | } | ||
| 1092 | #endif | ||
| 1093 | EXPORT_SYMBOL_GPL(lis3lv02d_init_dt); | ||
| 1094 | |||
| 946 | /* | 1095 | /* |
| 947 | * Initialise the accelerometer and the various subsystems. | 1096 | * Initialise the accelerometer and the various subsystems. |
| 948 | * Should be rather independent of the bus system. | 1097 | * Should be rather independent of the bus system. |
| @@ -953,6 +1102,10 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3) | |||
| 953 | irq_handler_t thread_fn; | 1102 | irq_handler_t thread_fn; |
| 954 | int irq_flags = 0; | 1103 | int irq_flags = 0; |
| 955 | 1104 | ||
| 1105 | err = lis3lv02d_init_dt(lis3); | ||
| 1106 | if (err < 0) | ||
| 1107 | return err; | ||
| 1108 | |||
| 956 | lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I); | 1109 | lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I); |
| 957 | 1110 | ||
| 958 | switch (lis3->whoami) { | 1111 | switch (lis3->whoami) { |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index 387504a37937..2e0700baa584 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h | |||
| @@ -314,6 +314,10 @@ struct lis3lv02d { | |||
| 314 | 314 | ||
| 315 | struct lis3lv02d_platform_data *pdata; /* for passing board config */ | 315 | struct lis3lv02d_platform_data *pdata; /* for passing board config */ |
| 316 | struct mutex mutex; /* Serialize poll and selftest */ | 316 | struct mutex mutex; /* Serialize poll and selftest */ |
| 317 | |||
| 318 | #ifdef CONFIG_OF | ||
| 319 | struct device_node *of_node; | ||
| 320 | #endif | ||
| 317 | }; | 321 | }; |
| 318 | 322 | ||
| 319 | int lis3lv02d_init_device(struct lis3lv02d *lis3); | 323 | int lis3lv02d_init_device(struct lis3lv02d *lis3); |
