diff options
author | Alexander Holler <holler@ahsoftware.de> | 2013-07-03 18:07:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 19:07:54 -0400 |
commit | c67d96e317510e63e8a24d3a5742dd47b21c3340 (patch) | |
tree | 87b88f4d82d827ebaffccc1f7da2f47ffd2413e7 | |
parent | 7e3c741abdae964b8f8aa9f46cf51143e2d0f686 (diff) |
rtc: rtc-hid-sensor-time: allow 16 and 32 bit values for all attributes.
There is no real reason to not support 16 or 32 bit values too.
Signed-off-by: Alexander Holler <holler@ahsoftware.de>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Jonathan Cameron <jic23@cam.ac.uk>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/rtc/rtc-hid-sensor-time.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index b8c1b106a0b7..7273b0139e5c 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c | |||
@@ -76,6 +76,20 @@ static int hid_time_proc_event(struct hid_sensor_hub_device *hsdev, | |||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
78 | 78 | ||
79 | static u32 hid_time_value(size_t raw_len, char *raw_data) | ||
80 | { | ||
81 | switch (raw_len) { | ||
82 | case 1: | ||
83 | return *(u8 *)raw_data; | ||
84 | case 2: | ||
85 | return *(u16 *)raw_data; | ||
86 | case 4: | ||
87 | return *(u32 *)raw_data; | ||
88 | default: | ||
89 | return (u32)(~0U); /* 0xff... or -1 to denote an error */ | ||
90 | } | ||
91 | } | ||
92 | |||
79 | static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev, | 93 | static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev, |
80 | unsigned usage_id, size_t raw_len, | 94 | unsigned usage_id, size_t raw_len, |
81 | char *raw_data, void *priv) | 95 | char *raw_data, void *priv) |
@@ -85,29 +99,35 @@ static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev, | |||
85 | 99 | ||
86 | switch (usage_id) { | 100 | switch (usage_id) { |
87 | case HID_USAGE_SENSOR_TIME_YEAR: | 101 | case HID_USAGE_SENSOR_TIME_YEAR: |
102 | /* | ||
103 | * The draft for HID-sensors (HUTRR39) currently doesn't define | ||
104 | * the range for the year attribute. Therefor we support | ||
105 | * 8 bit (0-99) and 16 or 32 bits (full) as size for the year. | ||
106 | */ | ||
88 | if (raw_len == 1) { | 107 | if (raw_len == 1) { |
89 | time_buf->tm_year = *(u8 *)raw_data; | 108 | time_buf->tm_year = *(u8 *)raw_data; |
90 | if (time_buf->tm_year < 70) | 109 | if (time_buf->tm_year < 70) |
91 | /* assume we are in 1970...2069 */ | 110 | /* assume we are in 1970...2069 */ |
92 | time_buf->tm_year += 100; | 111 | time_buf->tm_year += 100; |
93 | } else | 112 | } else |
94 | time_buf->tm_year = *(u16 *)raw_data-1900; | 113 | time_buf->tm_year = |
114 | (int)hid_time_value(raw_len, raw_data)-1900; | ||
95 | break; | 115 | break; |
96 | case HID_USAGE_SENSOR_TIME_MONTH: | 116 | case HID_USAGE_SENSOR_TIME_MONTH: |
97 | /* sensor sending the month as 1-12, we need 0-11 */ | 117 | /* sensors are sending the month as 1-12, we need 0-11 */ |
98 | time_buf->tm_mon = *(u8 *)raw_data-1; | 118 | time_buf->tm_mon = (int)hid_time_value(raw_len, raw_data)-1; |
99 | break; | 119 | break; |
100 | case HID_USAGE_SENSOR_TIME_DAY: | 120 | case HID_USAGE_SENSOR_TIME_DAY: |
101 | time_buf->tm_mday = *(u8 *)raw_data; | 121 | time_buf->tm_mday = (int)hid_time_value(raw_len, raw_data); |
102 | break; | 122 | break; |
103 | case HID_USAGE_SENSOR_TIME_HOUR: | 123 | case HID_USAGE_SENSOR_TIME_HOUR: |
104 | time_buf->tm_hour = *(u8 *)raw_data; | 124 | time_buf->tm_hour = (int)hid_time_value(raw_len, raw_data); |
105 | break; | 125 | break; |
106 | case HID_USAGE_SENSOR_TIME_MINUTE: | 126 | case HID_USAGE_SENSOR_TIME_MINUTE: |
107 | time_buf->tm_min = *(u8 *)raw_data; | 127 | time_buf->tm_min = (int)hid_time_value(raw_len, raw_data); |
108 | break; | 128 | break; |
109 | case HID_USAGE_SENSOR_TIME_SECOND: | 129 | case HID_USAGE_SENSOR_TIME_SECOND: |
110 | time_buf->tm_sec = *(u8 *)raw_data; | 130 | time_buf->tm_sec = (int)hid_time_value(raw_len, raw_data); |
111 | break; | 131 | break; |
112 | default: | 132 | default: |
113 | return -EINVAL; | 133 | return -EINVAL; |
@@ -153,28 +173,13 @@ static int hid_time_parse_report(struct platform_device *pdev, | |||
153 | "not all needed attributes inside the same report!\n"); | 173 | "not all needed attributes inside the same report!\n"); |
154 | return -EINVAL; | 174 | return -EINVAL; |
155 | } | 175 | } |
156 | if (time_state->info[i].size != 1) { | 176 | if (time_state->info[i].size == 3 || |
157 | /* | 177 | time_state->info[i].size > 4) { |
158 | * The draft for HID-sensors (HUTRR39) currently | 178 | dev_err(&pdev->dev, |
159 | * doesn't define the range for the year attribute. | 179 | "attribute '%s' not 8, 16 or 32 bits wide!\n", |
160 | * Therefor we support both 8 bit (0-99) and 16 bit | ||
161 | * (full) as size for the year. | ||
162 | */ | ||
163 | if (time_state->info[i].attrib_id != | ||
164 | HID_USAGE_SENSOR_TIME_YEAR) { | ||
165 | dev_err(&pdev->dev, | ||
166 | "attribute '%s' not 8 bits wide!\n", | ||
167 | hid_time_attrib_name( | ||
168 | time_state->info[i].attrib_id)); | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | if (time_state->info[i].size != 2) { | ||
172 | dev_err(&pdev->dev, | ||
173 | "attribute '%s' not 8 or 16 bits wide!\n", | ||
174 | hid_time_attrib_name( | 180 | hid_time_attrib_name( |
175 | time_state->info[i].attrib_id)); | 181 | time_state->info[i].attrib_id)); |
176 | return -EINVAL; | 182 | return -EINVAL; |
177 | } | ||
178 | } | 183 | } |
179 | if (time_state->info[i].units != | 184 | if (time_state->info[i].units != |
180 | HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED && | 185 | HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED && |