aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/dell-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/dell-laptop.c')
-rw-r--r--drivers/platform/x86/dell-laptop.c101
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
177static int dell_rfkill_set(int radio, enum rfkill_state state) 177static 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
189static int dell_wifi_set(void *data, enum rfkill_state state) 190static void dell_rfkill_query(struct rfkill *rfkill, void *data)
190{
191 return dell_rfkill_set(1, state);
192}
193
194static int dell_bluetooth_set(void *data, enum rfkill_state state)
195{
196 return dell_rfkill_set(2, state);
197}
198
199static int dell_wwan_set(void *data, enum rfkill_state state)
200{
201 return dell_rfkill_set(3, state);
202}
203
204static 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
225static int dell_wifi_get(void *data, enum rfkill_state *state)
226{
227 return dell_rfkill_get(17, state);
228}
229
230static int dell_bluetooth_get(void *data, enum rfkill_state *state)
231{
232 return dell_rfkill_get(18, state);
233} 202}
234 203
235static int dell_wwan_get(void *data, enum rfkill_state *state) 204static 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
240static int dell_setup_rfkill(void) 209static 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;
287err_wwan: 257err_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 }
294err_bluetooth: 261err_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 }
301err_wifi: 265err_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}