blob: d015ad3c46002b785674ab8e1e11e3db5552b846 [file] [log] [blame]
Pavan Savoyd0088ce2010-04-08 13:16:54 -05001/*
2 * Shared Transport Line discipline driver Core
3 * Init Manager module responsible for GPIO control
4 * and firmware download
5 * Copyright (C) 2009 Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#define pr_fmt(fmt) "(stk) :" fmt
23#include <linux/platform_device.h>
24#include <linux/jiffies.h>
25#include <linux/firmware.h>
26#include <linux/delay.h>
27#include <linux/wait.h>
28#include <linux/gpio.h>
29
30#include <linux/sched.h>
31
32#include "st_kim.h"
33/* understand BT events for fw response */
34#include <net/bluetooth/bluetooth.h>
35#include <net/bluetooth/hci_core.h>
36#include <net/bluetooth/hci.h>
37
38
39static int kim_probe(struct platform_device *pdev);
40static int kim_remove(struct platform_device *pdev);
41
42/* KIM platform device driver structure */
43static struct platform_driver kim_platform_driver = {
44 .probe = kim_probe,
45 .remove = kim_remove,
46 /* TODO: ST driver power management during suspend/resume ?
47 */
48#if 0
49 .suspend = kim_suspend,
50 .resume = kim_resume,
51#endif
52 .driver = {
53 .name = "kim",
54 .owner = THIS_MODULE,
55 },
56};
57
Pavan Savoyd0088ce2010-04-08 13:16:54 -050058static ssize_t show_pid(struct device *dev, struct device_attribute
Naveen Jaine2a53282010-06-09 03:45:33 -050059 *attr, char *buf);
Pavan Savoyd0088ce2010-04-08 13:16:54 -050060static ssize_t store_pid(struct device *dev, struct device_attribute
Naveen Jaine2a53282010-06-09 03:45:33 -050061 *devattr, char *buf, size_t count);
Pavan Savoyd0088ce2010-04-08 13:16:54 -050062static ssize_t show_list(struct device *dev, struct device_attribute
Naveen Jaine2a53282010-06-09 03:45:33 -050063 *attr, char *buf);
64static ssize_t show_version(struct device *dev, struct device_attribute
65 *attr, char *buf);
Pavan Savoyd0088ce2010-04-08 13:16:54 -050066/* structures specific for sysfs entries */
67static struct kobj_attribute pid_attr =
68__ATTR(pid, 0644, (void *)show_pid, (void *)store_pid);
69
70static struct kobj_attribute list_protocols =
71__ATTR(protocols, 0444, (void *)show_list, NULL);
72
Naveen Jaine2a53282010-06-09 03:45:33 -050073static struct kobj_attribute chip_version =
74__ATTR(version, 0444, (void *)show_version, NULL);
75
Pavan Savoyd0088ce2010-04-08 13:16:54 -050076static struct attribute *uim_attrs[] = {
77 &pid_attr.attr,
78 /* add more debug sysfs entries */
79 &list_protocols.attr,
Naveen Jaine2a53282010-06-09 03:45:33 -050080 &chip_version.attr,
Pavan Savoyd0088ce2010-04-08 13:16:54 -050081 NULL,
82};
83
84static struct attribute_group uim_attr_grp = {
85 .attrs = uim_attrs,
86};
Naveen Jainb38fc2d2010-06-09 03:45:32 -050087
Pavan Savoyd0088ce2010-04-08 13:16:54 -050088static int kim_toggle_radio(void*, bool);
89static const struct rfkill_ops kim_rfkill_ops = {
90 .set_block = kim_toggle_radio,
91};
Pavan Savoyd0088ce2010-04-08 13:16:54 -050092
93/* strings to be used for rfkill entries and by
94 * ST Core to be used for sysfs debug entry
95 */
96#define PROTO_ENTRY(type, name) name
97const unsigned char *protocol_names[] = {
98 PROTO_ENTRY(ST_BT, "Bluetooth"),
99 PROTO_ENTRY(ST_FM, "FM"),
100 PROTO_ENTRY(ST_GPS, "GPS"),
101};
102
103struct kim_data_s *kim_gdata;
104
105/**********************************************************************/
106/* internal functions */
107
108/*
109 * function to return whether the firmware response was proper
110 * in case of error don't complete so that waiting for proper
111 * response times out
112 */
113void validate_firmware_response(struct sk_buff *skb)
114{
115 if (unlikely(skb->data[5] != 0)) {
116 pr_err("no proper response during fw download");
117 pr_err("data6 %x", skb->data[5]);
118 return; /* keep waiting for the proper response */
119 }
120 /* becos of all the script being downloaded */
121 complete_all(&kim_gdata->kim_rcvd);
122 kfree_skb(skb);
123}
124
125/* check for data len received inside kim_int_recv
126 * most often hit the last case to update state to waiting for data
127 */
128static inline int kim_check_data_len(int len)
129{
130 register int room = skb_tailroom(kim_gdata->rx_skb);
131
132 pr_info("len %d room %d", len, room);
133
134 if (!len) {
135 validate_firmware_response(kim_gdata->rx_skb);
136 } else if (len > room) {
137 /* Received packet's payload length is larger.
138 * We can't accommodate it in created skb.
139 */
140 pr_err("Data length is too large len %d room %d", len,
141 room);
142 kfree_skb(kim_gdata->rx_skb);
143 } else {
144 /* Packet header has non-zero payload length and
145 * we have enough space in created skb. Lets read
146 * payload data */
147 kim_gdata->rx_state = ST_BT_W4_DATA;
148 kim_gdata->rx_count = len;
149 return len;
150 }
151
152 /* Change ST LL state to continue to process next
153 * packet */
154 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
155 kim_gdata->rx_skb = NULL;
156 kim_gdata->rx_count = 0;
157
158 return 0;
159}
160
161/* receive function called during firmware download
162 * - firmware download responses on different UART drivers
163 * have been observed to come in bursts of different
164 * tty_receive and hence the logic
165 */
166void kim_int_recv(const unsigned char *data, long count)
167{
168 register char *ptr;
169 struct hci_event_hdr *eh;
170 register int len = 0, type = 0;
171
172 pr_info("%s", __func__);
173 /* Decode received bytes here */
174 ptr = (char *)data;
175 if (unlikely(ptr == NULL)) {
176 pr_err(" received null from TTY ");
177 return;
178 }
179 while (count) {
180 if (kim_gdata->rx_count) {
181 len = min_t(unsigned int, kim_gdata->rx_count, count);
182 memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len);
183 kim_gdata->rx_count -= len;
184 count -= len;
185 ptr += len;
186
187 if (kim_gdata->rx_count)
188 continue;
189
190 /* Check ST RX state machine , where are we? */
191 switch (kim_gdata->rx_state) {
192 /* Waiting for complete packet ? */
193 case ST_BT_W4_DATA:
194 pr_info("Complete pkt received");
195 validate_firmware_response(kim_gdata->rx_skb);
196 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
197 kim_gdata->rx_skb = NULL;
198 continue;
199 /* Waiting for Bluetooth event header ? */
200 case ST_BT_W4_EVENT_HDR:
201 eh = (struct hci_event_hdr *)kim_gdata->
202 rx_skb->data;
203 pr_info("Event header: evt 0x%2.2x"
204 "plen %d", eh->evt, eh->plen);
205 kim_check_data_len(eh->plen);
206 continue;
207 } /* end of switch */
208 } /* end of if rx_state */
209 switch (*ptr) {
210 /* Bluetooth event packet? */
211 case HCI_EVENT_PKT:
212 pr_info("Event packet");
213 kim_gdata->rx_state = ST_BT_W4_EVENT_HDR;
214 kim_gdata->rx_count = HCI_EVENT_HDR_SIZE;
215 type = HCI_EVENT_PKT;
216 break;
217 default:
218 pr_info("unknown packet");
219 ptr++;
220 count--;
221 continue;
222 } /* end of switch *ptr */
223 ptr++;
224 count--;
225 kim_gdata->rx_skb =
226 bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
227 if (!kim_gdata->rx_skb) {
228 pr_err("can't allocate mem for new packet");
229 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
230 kim_gdata->rx_count = 0;
231 return;
232 } /* not necessary in this case */
233 bt_cb(kim_gdata->rx_skb)->pkt_type = type;
234 } /* end of while count */
235 pr_info("done %s", __func__);
236 return;
237}
238
239static long read_local_version(char *bts_scr_name)
240{
241 unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0;
242 char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 };
243
244 pr_info("%s", __func__);
245
246 INIT_COMPLETION(kim_gdata->kim_rcvd);
247 if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) {
248 pr_err("kim: couldn't write 4 bytes");
249 return ST_ERR_FAILURE;
250 }
251
252 if (!wait_for_completion_timeout
253 (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
254 pr_err(" waiting for ver info- timed out ");
255 return ST_ERR_FAILURE;
256 }
257
258 version =
Naveen Jaine2a53282010-06-09 03:45:33 -0500259 MAKEWORD(kim_gdata->resp_buffer[13],
260 kim_gdata->resp_buffer[14]);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500261 chip = (version & 0x7C00) >> 10;
262 min_ver = (version & 0x007F);
263 maj_ver = (version & 0x0380) >> 7;
264
265 if (version & 0x8000)
266 maj_ver |= 0x0008;
267
268 sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
Naveen Jaine2a53282010-06-09 03:45:33 -0500269
270 /* to be accessed later via sysfs entry */
271 kim_gdata->version.full = version;
272 kim_gdata->version.chip = chip;
273 kim_gdata->version.maj_ver = maj_ver;
274 kim_gdata->version.min_ver = min_ver;
275
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500276 pr_info("%s", bts_scr_name);
277 return ST_SUCCESS;
278}
279
280/* internal function which parses through the .bts firmware script file
281 * intreprets SEND, DELAY actions only as of now
282 */
283static long download_firmware(void)
284{
285 long err = ST_SUCCESS;
286 long len = 0;
287 register unsigned char *ptr = NULL;
288 register unsigned char *action_ptr = NULL;
289 unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
290
291 pr_info("%s", __func__);
292
293 err = read_local_version(bts_scr_name);
294 if (err != ST_SUCCESS) {
295 pr_err("kim: failed to read local ver");
296 return err;
297 }
298 err =
299 request_firmware(&kim_gdata->fw_entry, bts_scr_name,
300 &kim_gdata->kim_pdev->dev);
301 if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) ||
302 (kim_gdata->fw_entry->size == 0))) {
303 pr_err(" request_firmware failed(errno %ld) for %s", err,
304 bts_scr_name);
305 return ST_ERR_FAILURE;
306 }
307 ptr = (void *)kim_gdata->fw_entry->data;
308 len = kim_gdata->fw_entry->size;
309 /* bts_header to remove out magic number and
310 * version
311 */
312 ptr += sizeof(struct bts_header);
313 len -= sizeof(struct bts_header);
314
315 while (len > 0 && ptr) {
316 pr_info(" action size %d, type %d ",
317 ((struct bts_action *)ptr)->size,
318 ((struct bts_action *)ptr)->type);
319
320 switch (((struct bts_action *)ptr)->type) {
321 case ACTION_SEND_COMMAND: /* action send */
322 action_ptr = &(((struct bts_action *)ptr)->data[0]);
323 if (unlikely
324 (((struct hci_command *)action_ptr)->opcode ==
325 0xFF36)) {
326 /* ignore remote change
327 * baud rate HCI VS command */
328 pr_err
329 (" change remote baud\
330 rate command in firmware");
331 break;
332 }
333
334 INIT_COMPLETION(kim_gdata->kim_rcvd);
335 err = st_int_write(kim_gdata->core_data,
336 ((struct bts_action_send *)action_ptr)->data,
337 ((struct bts_action *)ptr)->size);
338 if (unlikely(err < 0)) {
339 release_firmware(kim_gdata->fw_entry);
340 return ST_ERR_FAILURE;
341 }
342 if (!wait_for_completion_timeout
343 (&kim_gdata->kim_rcvd,
344 msecs_to_jiffies(CMD_RESP_TIME))) {
345 pr_err
346 (" response timeout during fw download ");
347 /* timed out */
348 release_firmware(kim_gdata->fw_entry);
349 return ST_ERR_FAILURE;
350 }
351 break;
352 case ACTION_DELAY: /* sleep */
353 pr_info("sleep command in scr");
354 action_ptr = &(((struct bts_action *)ptr)->data[0]);
355 mdelay(((struct bts_action_delay *)action_ptr)->msec);
356 break;
357 }
358 len =
359 len - (sizeof(struct bts_action) +
360 ((struct bts_action *)ptr)->size);
361 ptr =
362 ptr + sizeof(struct bts_action) +
363 ((struct bts_action *)ptr)->size;
364 }
365 /* fw download complete */
366 release_firmware(kim_gdata->fw_entry);
367 return ST_SUCCESS;
368}
369
370/**********************************************************************/
371/* functions called from ST core */
372
373/* function to toggle the GPIO
374 * needs to know whether the GPIO is active high or active low
375 */
376void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
377{
378 pr_info(" %s ", __func__);
379
380 if (kim_gdata->gpios[type] == -1) {
381 pr_info(" gpio not requested for protocol %s",
382 protocol_names[type]);
383 return;
384 }
385 switch (type) {
386 case ST_BT:
387 /*Do Nothing */
388 break;
389
390 case ST_FM:
391 if (state == KIM_GPIO_ACTIVE)
392 gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_LOW);
393 else
394 gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_HIGH);
395 break;
396
397 case ST_GPS:
398 if (state == KIM_GPIO_ACTIVE)
399 gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_HIGH);
400 else
401 gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW);
402 break;
403
404 case ST_MAX:
405 default:
406 break;
407 }
408
409 return;
410}
411
412/* called from ST Core, when REG_IN_PROGRESS (registration in progress)
413 * can be because of
414 * 1. response to read local version
415 * 2. during send/recv's of firmware download
416 */
417void st_kim_recv(void *disc_data, const unsigned char *data, long count)
418{
419 pr_info(" %s ", __func__);
420 /* copy to local buffer */
421 if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
422 /* must be the read_ver_cmd */
423 memcpy(kim_gdata->resp_buffer, data, count);
424 complete_all(&kim_gdata->kim_rcvd);
425 return;
426 } else {
427 kim_int_recv(data, count);
428 /* either completes or times out */
429 }
430 return;
431}
432
433/* to signal completion of line discipline installation
434 * called from ST Core, upon tty_open
435 */
436void st_kim_complete(void)
437{
438 complete(&kim_gdata->ldisc_installed);
439}
440
441/* called from ST Core upon 1st registration
442*/
443long st_kim_start(void)
444{
445 long err = ST_SUCCESS;
446 long retry = POR_RETRY_COUNT;
447 pr_info(" %s", __func__);
448
449 do {
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500450 /* TODO: this is only because rfkill sub-system
451 * doesn't send events to user-space if the state
452 * isn't changed
453 */
454 rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500455 /* Configure BT nShutdown to HIGH state */
456 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
457 mdelay(5); /* FIXME: a proper toggle */
458 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH);
459 mdelay(100);
460 /* re-initialize the completion */
461 INIT_COMPLETION(kim_gdata->ldisc_installed);
Naveen Jainb38fc2d2010-06-09 03:45:32 -0500462#if 0 /* older way of signalling user-space UIM */
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500463 /* send signal to UIM */
464 err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 0);
465 if (err != 0) {
466 pr_info(" sending SIGUSR2 to uim failed %ld", err);
467 err = ST_ERR_FAILURE;
468 continue;
469 }
Naveen Jainb38fc2d2010-06-09 03:45:32 -0500470#endif
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500471 /* unblock and send event to UIM via /dev/rfkill */
472 rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 0);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500473 /* wait for ldisc to be installed */
474 err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
475 msecs_to_jiffies(LDISC_TIME));
476 if (!err) { /* timeout */
477 pr_err("line disc installation timed out ");
478 err = ST_ERR_FAILURE;
479 continue;
480 } else {
481 /* ldisc installed now */
482 pr_info(" line discipline installed ");
483 err = download_firmware();
484 if (err != ST_SUCCESS) {
485 pr_err("download firmware failed");
486 continue;
487 } else { /* on success don't retry */
488 break;
489 }
490 }
491 } while (retry--);
492 return err;
493}
494
495/* called from ST Core, on the last un-registration
496*/
497long st_kim_stop(void)
498{
499 long err = ST_SUCCESS;
500
501 INIT_COMPLETION(kim_gdata->ldisc_installed);
Naveen Jainb38fc2d2010-06-09 03:45:32 -0500502#if 0 /* older way of signalling user-space UIM */
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500503 /* send signal to UIM */
504 err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 1);
505 if (err != 0) {
506 pr_err("sending SIGUSR2 to uim failed %ld", err);
507 return ST_ERR_FAILURE;
508 }
Naveen Jainb38fc2d2010-06-09 03:45:32 -0500509#endif
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500510 /* set BT rfkill to be blocked */
511 err = rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500512
513 /* wait for ldisc to be un-installed */
514 err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
515 msecs_to_jiffies(LDISC_TIME));
516 if (!err) { /* timeout */
517 pr_err(" timed out waiting for ldisc to be un-installed");
518 return ST_ERR_FAILURE;
519 }
520
521 /* By default configure BT nShutdown to LOW state */
522 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
523 mdelay(1);
524 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH);
525 mdelay(1);
526 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
527 return err;
528}
529
530/**********************************************************************/
531/* functions called from subsystems */
Naveen Jaine2a53282010-06-09 03:45:33 -0500532/* called when sysfs entry is read from */
533
534static ssize_t show_version(struct device *dev, struct device_attribute
535 *attr, char *buf)
536{
537 sprintf(buf, "%04X %d.%d.%d", kim_gdata->version.full,
538 kim_gdata->version.chip, kim_gdata->version.maj_ver,
539 kim_gdata->version.min_ver);
540 return strlen(buf);
541}
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500542
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500543/* called when sysfs entry is written to */
544static ssize_t store_pid(struct device *dev, struct device_attribute
545 *devattr, char *buf, size_t count)
546{
547 pr_info("%s: pid %s ", __func__, buf);
548 sscanf(buf, "%ld", &kim_gdata->uim_pid);
549 /* to be made use by kim_start to signal SIGUSR2
550 */
551 return strlen(buf);
552}
553
554/* called when sysfs entry is read from */
555static ssize_t show_pid(struct device *dev, struct device_attribute
556 *attr, char *buf)
557{
558 sprintf(buf, "%ld", kim_gdata->uim_pid);
559 return strlen(buf);
560}
561
562/* called when sysfs entry is read from */
563static ssize_t show_list(struct device *dev, struct device_attribute
564 *attr, char *buf)
565{
566 kim_st_list_protocols(kim_gdata->core_data, buf);
567 return strlen(buf);
568}
569
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500570/* function called from rfkill subsystem, when someone from
571 * user space would write 0/1 on the sysfs entry
572 * /sys/class/rfkill/rfkill0,1,3/state
573 */
574static int kim_toggle_radio(void *data, bool blocked)
575{
576 enum proto_type type = *((enum proto_type *)data);
577 pr_info(" %s: %d ", __func__, type);
578
579 switch (type) {
580 case ST_BT:
581 /* do nothing */
582 break;
583 case ST_FM:
584 case ST_GPS:
585 if (blocked)
586 st_kim_chip_toggle(type, KIM_GPIO_INACTIVE);
587 else
588 st_kim_chip_toggle(type, KIM_GPIO_ACTIVE);
589 break;
590 case ST_MAX:
591 pr_err(" wrong proto type ");
592 break;
593 }
594 return ST_SUCCESS;
595}
596
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500597void st_kim_ref(struct st_data_s **core_data)
598{
599 *core_data = kim_gdata->core_data;
600}
601
602/**********************************************************************/
603/* functions called from platform device driver subsystem
604 * need to have a relevant platform device entry in the platform's
605 * board-*.c file
606 */
607
608static int kim_probe(struct platform_device *pdev)
609{
610 long status;
611 long proto;
612 long *gpios = pdev->dev.platform_data;
613
614 status = st_core_init(&kim_gdata->core_data);
615 if (status != 0) {
616 pr_err(" ST core init failed");
617 return ST_ERR_FAILURE;
618 }
619
620 for (proto = 0; proto < ST_MAX; proto++) {
621 kim_gdata->gpios[proto] = gpios[proto];
622 pr_info(" %ld gpio to be requested", gpios[proto]);
623 }
624
625 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
626 /* Claim the Bluetooth/FM/GPIO
627 * nShutdown gpio from the system
628 */
629 status = gpio_request(gpios[proto], "kim");
630 if (unlikely(status)) {
631 pr_err(" gpio %ld request failed ", gpios[proto]);
632 proto -= 1;
633 while (proto >= 0) {
634 if (gpios[proto] != -1)
635 gpio_free(gpios[proto]);
636 }
637 return status;
638 }
639
640 /* Configure nShutdown GPIO as output=0 */
641 status =
642 gpio_direction_output(gpios[proto], 0);
643 if (unlikely(status)) {
644 pr_err(" unable to configure gpio %ld",
645 gpios[proto]);
646 proto -= 1;
647 while (proto >= 0) {
648 if (gpios[proto] != -1)
649 gpio_free(gpios[proto]);
650 }
651 return status;
652 }
653 }
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500654 /* get reference of pdev for request_firmware
655 */
656 kim_gdata->kim_pdev = pdev;
657 init_completion(&kim_gdata->kim_rcvd);
658 init_completion(&kim_gdata->ldisc_installed);
Naveen Jainb38fc2d2010-06-09 03:45:32 -0500659
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500660 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
661 /* TODO: should all types be rfkill_type_bt ? */
662 kim_gdata->rf_protos[proto] = proto;
663 kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto],
664 &pdev->dev, RFKILL_TYPE_BLUETOOTH,
665 &kim_rfkill_ops, &kim_gdata->rf_protos[proto]);
666 if (kim_gdata->rfkill[proto] == NULL) {
667 pr_err("cannot create rfkill entry for gpio %ld",
668 gpios[proto]);
669 continue;
670 }
671 /* block upon creation */
672 rfkill_init_sw_state(kim_gdata->rfkill[proto], 1);
673 status = rfkill_register(kim_gdata->rfkill[proto]);
674 if (unlikely(status)) {
675 pr_err("rfkill registration failed for gpio %ld",
676 gpios[proto]);
677 rfkill_unregister(kim_gdata->rfkill[proto]);
678 continue;
679 }
680 pr_info("rfkill entry created for %ld", gpios[proto]);
681 }
Naveen Jaine2a53282010-06-09 03:45:33 -0500682
683 if (sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp)) {
684 pr_err(" sysfs entry creation failed");
685 return -1;
686 }
687 pr_info(" sysfs entries created ");
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500688 return ST_SUCCESS;
689}
690
691static int kim_remove(struct platform_device *pdev)
692{
693 /* free the GPIOs requested
694 */
695 long *gpios = pdev->dev.platform_data;
696 long proto;
697
698 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
699 /* Claim the Bluetooth/FM/GPIO
700 * nShutdown gpio from the system
701 */
702 gpio_free(gpios[proto]);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500703 rfkill_unregister(kim_gdata->rfkill[proto]);
704 rfkill_destroy(kim_gdata->rfkill[proto]);
705 kim_gdata->rfkill[proto] = NULL;
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500706 }
707 pr_info("kim: GPIO Freed");
Naveen Jaine2a53282010-06-09 03:45:33 -0500708 sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
Pavan Savoyd0088ce2010-04-08 13:16:54 -0500709 kim_gdata->kim_pdev = NULL;
710 st_core_exit(kim_gdata->core_data);
711 return ST_SUCCESS;
712}
713
714/**********************************************************************/
715/* entry point for ST KIM module, called in from ST Core */
716
717static int __init st_kim_init(void)
718{
719 long ret = ST_SUCCESS;
720 kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
721 if (!kim_gdata) {
722 pr_err("no mem to allocate");
723 return -ENOMEM;
724 }
725
726 ret = platform_driver_register(&kim_platform_driver);
727 if (ret != 0) {
728 pr_err("platform drv registration failed");
729 return ST_ERR_FAILURE;
730 }
731 return ST_SUCCESS;
732}
733
734static void __exit st_kim_deinit(void)
735{
736 /* the following returns void */
737 platform_driver_unregister(&kim_platform_driver);
738 kfree(kim_gdata);
739 kim_gdata = NULL;
740}
741
742
743module_init(st_kim_init);
744module_exit(st_kim_deinit);
745MODULE_AUTHOR("Pavan Savoy <pavan_savoy@ti.com>");
746MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips ");
747MODULE_LICENSE("GPL");