diff options
Diffstat (limited to 'drivers/platform/x86/dell-laptop.c')
-rw-r--r-- | drivers/platform/x86/dell-laptop.c | 101 |
1 files changed, 32 insertions, 69 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index af9f43021172..2faf0e14f05a 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -174,10 +174,11 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
174 | result[3]: NVRAM format version number | 174 | result[3]: NVRAM format version number |
175 | */ | 175 | */ |
176 | 176 | ||
177 | static int dell_rfkill_set(int radio, enum rfkill_state state) | 177 | static int dell_rfkill_set(void *data, bool blocked) |
178 | { | 178 | { |
179 | struct calling_interface_buffer buffer; | 179 | struct calling_interface_buffer buffer; |
180 | int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; | 180 | int disable = blocked ? 0 : 1; |
181 | unsigned long radio = (unsigned long)data; | ||
181 | 182 | ||
182 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 183 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); |
183 | buffer.input[0] = (1 | (radio<<8) | (disable << 16)); | 184 | buffer.input[0] = (1 | (radio<<8) | (disable << 16)); |
@@ -186,56 +187,24 @@ static int dell_rfkill_set(int radio, enum rfkill_state state) | |||
186 | return 0; | 187 | return 0; |
187 | } | 188 | } |
188 | 189 | ||
189 | static int dell_wifi_set(void *data, enum rfkill_state state) | 190 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) |
190 | { | ||
191 | return dell_rfkill_set(1, state); | ||
192 | } | ||
193 | |||
194 | static int dell_bluetooth_set(void *data, enum rfkill_state state) | ||
195 | { | ||
196 | return dell_rfkill_set(2, state); | ||
197 | } | ||
198 | |||
199 | static int dell_wwan_set(void *data, enum rfkill_state state) | ||
200 | { | ||
201 | return dell_rfkill_set(3, state); | ||
202 | } | ||
203 | |||
204 | static int dell_rfkill_get(int bit, enum rfkill_state *state) | ||
205 | { | 191 | { |
206 | struct calling_interface_buffer buffer; | 192 | struct calling_interface_buffer buffer; |
207 | int status; | 193 | int status; |
208 | int new_state = RFKILL_STATE_HARD_BLOCKED; | 194 | int bit = (unsigned long)data + 16; |
209 | 195 | ||
210 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 196 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); |
211 | dell_send_request(&buffer, 17, 11); | 197 | dell_send_request(&buffer, 17, 11); |
212 | status = buffer.output[1]; | 198 | status = buffer.output[1]; |
213 | 199 | ||
214 | if (status & (1<<16)) | 200 | if (status & BIT(bit)) |
215 | new_state = RFKILL_STATE_SOFT_BLOCKED; | 201 | rfkill_set_hw_state(rfkill, !!(status & BIT(16))); |
216 | |||
217 | if (status & (1<<bit)) | ||
218 | *state = new_state; | ||
219 | else | ||
220 | *state = RFKILL_STATE_UNBLOCKED; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int dell_wifi_get(void *data, enum rfkill_state *state) | ||
226 | { | ||
227 | return dell_rfkill_get(17, state); | ||
228 | } | ||
229 | |||
230 | static int dell_bluetooth_get(void *data, enum rfkill_state *state) | ||
231 | { | ||
232 | return dell_rfkill_get(18, state); | ||
233 | } | 202 | } |
234 | 203 | ||
235 | static int dell_wwan_get(void *data, enum rfkill_state *state) | 204 | static const struct rfkill_ops dell_rfkill_ops = { |
236 | { | 205 | .set_block = dell_rfkill_set, |
237 | return dell_rfkill_get(19, state); | 206 | .query = dell_rfkill_query, |
238 | } | 207 | }; |
239 | 208 | ||
240 | static int dell_setup_rfkill(void) | 209 | static int dell_setup_rfkill(void) |
241 | { | 210 | { |
@@ -248,36 +217,37 @@ static int dell_setup_rfkill(void) | |||
248 | status = buffer.output[1]; | 217 | status = buffer.output[1]; |
249 | 218 | ||
250 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { | 219 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { |
251 | wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN); | 220 | wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN, |
252 | if (!wifi_rfkill) | 221 | &dell_rfkill_ops, (void *) 1); |
222 | if (!wifi_rfkill) { | ||
223 | ret = -ENOMEM; | ||
253 | goto err_wifi; | 224 | goto err_wifi; |
254 | wifi_rfkill->name = "dell-wifi"; | 225 | } |
255 | wifi_rfkill->toggle_radio = dell_wifi_set; | ||
256 | wifi_rfkill->get_state = dell_wifi_get; | ||
257 | ret = rfkill_register(wifi_rfkill); | 226 | ret = rfkill_register(wifi_rfkill); |
258 | if (ret) | 227 | if (ret) |
259 | goto err_wifi; | 228 | goto err_wifi; |
260 | } | 229 | } |
261 | 230 | ||
262 | if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { | 231 | if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { |
263 | bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); | 232 | bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL, |
264 | if (!bluetooth_rfkill) | 233 | RFKILL_TYPE_BLUETOOTH, |
234 | &dell_rfkill_ops, (void *) 2); | ||
235 | if (!bluetooth_rfkill) { | ||
236 | ret = -ENOMEM; | ||
265 | goto err_bluetooth; | 237 | goto err_bluetooth; |
266 | bluetooth_rfkill->name = "dell-bluetooth"; | 238 | } |
267 | bluetooth_rfkill->toggle_radio = dell_bluetooth_set; | ||
268 | bluetooth_rfkill->get_state = dell_bluetooth_get; | ||
269 | ret = rfkill_register(bluetooth_rfkill); | 239 | ret = rfkill_register(bluetooth_rfkill); |
270 | if (ret) | 240 | if (ret) |
271 | goto err_bluetooth; | 241 | goto err_bluetooth; |
272 | } | 242 | } |
273 | 243 | ||
274 | if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { | 244 | if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { |
275 | wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); | 245 | wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN, |
276 | if (!wwan_rfkill) | 246 | &dell_rfkill_ops, (void *) 3); |
247 | if (!wwan_rfkill) { | ||
248 | ret = -ENOMEM; | ||
277 | goto err_wwan; | 249 | goto err_wwan; |
278 | wwan_rfkill->name = "dell-wwan"; | 250 | } |
279 | wwan_rfkill->toggle_radio = dell_wwan_set; | ||
280 | wwan_rfkill->get_state = dell_wwan_get; | ||
281 | ret = rfkill_register(wwan_rfkill); | 251 | ret = rfkill_register(wwan_rfkill); |
282 | if (ret) | 252 | if (ret) |
283 | goto err_wwan; | 253 | goto err_wwan; |
@@ -285,22 +255,15 @@ static int dell_setup_rfkill(void) | |||
285 | 255 | ||
286 | return 0; | 256 | return 0; |
287 | err_wwan: | 257 | err_wwan: |
288 | if (wwan_rfkill) | 258 | rfkill_destroy(wwan_rfkill); |
289 | rfkill_free(wwan_rfkill); | 259 | if (bluetooth_rfkill) |
290 | if (bluetooth_rfkill) { | ||
291 | rfkill_unregister(bluetooth_rfkill); | 260 | rfkill_unregister(bluetooth_rfkill); |
292 | bluetooth_rfkill = NULL; | ||
293 | } | ||
294 | err_bluetooth: | 261 | err_bluetooth: |
295 | if (bluetooth_rfkill) | 262 | rfkill_destroy(bluetooth_rfkill); |
296 | rfkill_free(bluetooth_rfkill); | 263 | if (wifi_rfkill) |
297 | if (wifi_rfkill) { | ||
298 | rfkill_unregister(wifi_rfkill); | 264 | rfkill_unregister(wifi_rfkill); |
299 | wifi_rfkill = NULL; | ||
300 | } | ||
301 | err_wifi: | 265 | err_wifi: |
302 | if (wifi_rfkill) | 266 | rfkill_destroy(wifi_rfkill); |
303 | rfkill_free(wifi_rfkill); | ||
304 | 267 | ||
305 | return ret; | 268 | return ret; |
306 | } | 269 | } |