aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/ti-st/st_kim.c
diff options
context:
space:
mode:
authorPavan Savoy <pavan_savoy@ti.com>2010-10-06 12:18:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-06 11:25:06 -0400
commita0cc2f3b51a8649da5262aba7501dc21738e1b8d (patch)
tree01f5a8a5fa8ef079de806fc192a1a400348d17ea /drivers/misc/ti-st/st_kim.c
parentaecac19179180b7d6cda13f598e314c0870aee80 (diff)
staging: ti-st: move TI_ST from staging to misc/
move the 3 source files st_core.c, st_kim.c and st_ll.c from staging to drivers/misc/. Texas Instrument's WiLink 7 chipset packs wireless technologies like Bluetooth, FM, GPS and WLAN into a single die. Among these the Bluetooth, FM Rx/Tx and GPS are interfaced to a apps processor over a single UART. This line discipline driver allows various protocol drivers such as Bluetooth BlueZ driver, FM V4L2 driver and GPS simple character device driver to communicate with its relevant core in the chip. Each protocol or technologies use a logical channel to communicate with chip. Bluetooth uses the HCI-H4 [channels 1-4], FM uses a CH-8 and GPS a CH-9 protocol. The driver also constitutes the TI HCI-LL Power Management protocol which use channels 30-33. Signed-off-by: Pavan Savoy <pavan_savoy@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/misc/ti-st/st_kim.c')
-rw-r--r--drivers/misc/ti-st/st_kim.c798
1 files changed, 798 insertions, 0 deletions
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
new file mode 100644
index 000000000000..6d23a7222627
--- /dev/null
+++ b/drivers/misc/ti-st/st_kim.c
@@ -0,0 +1,798 @@
1/*
2 * Shared Transport Line discipline driver Core
3 * Init Manager module responsible for GPIO control
4 * and firmware download
5 * Copyright (C) 2009-2010 Texas Instruments
6 * Author: Pavan Savoy <pavan_savoy@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#define pr_fmt(fmt) "(stk) :" fmt
24#include <linux/platform_device.h>
25#include <linux/jiffies.h>
26#include <linux/firmware.h>
27#include <linux/delay.h>
28#include <linux/wait.h>
29#include <linux/gpio.h>
30#include <linux/debugfs.h>
31#include <linux/seq_file.h>
32#include <linux/sched.h>
33#include <linux/rfkill.h>
34
35/* understand BT events for fw response */
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/hci.h>
39
40#include <linux/ti_wilink_st.h>
41
42
43static int kim_probe(struct platform_device *pdev);
44static int kim_remove(struct platform_device *pdev);
45
46/* KIM platform device driver structure */
47static struct platform_driver kim_platform_driver = {
48 .probe = kim_probe,
49 .remove = kim_remove,
50 /* TODO: ST driver power management during suspend/resume ?
51 */
52#if 0
53 .suspend = kim_suspend,
54 .resume = kim_resume,
55#endif
56 .driver = {
57 .name = "kim",
58 .owner = THIS_MODULE,
59 },
60};
61
62static int kim_toggle_radio(void*, bool);
63static const struct rfkill_ops kim_rfkill_ops = {
64 .set_block = kim_toggle_radio,
65};
66
67/* strings to be used for rfkill entries and by
68 * ST Core to be used for sysfs debug entry
69 */
70#define PROTO_ENTRY(type, name) name
71const unsigned char *protocol_names[] = {
72 PROTO_ENTRY(ST_BT, "Bluetooth"),
73 PROTO_ENTRY(ST_FM, "FM"),
74 PROTO_ENTRY(ST_GPS, "GPS"),
75};
76
77#define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */
78struct platform_device *st_kim_devices[MAX_ST_DEVICES];
79
80/**********************************************************************/
81/* internal functions */
82
83/**
84 * st_get_plat_device -
85 * function which returns the reference to the platform device
86 * requested by id. As of now only 1 such device exists (id=0)
87 * the context requesting for reference can get the id to be
88 * requested by a. The protocol driver which is registering or
89 * b. the tty device which is opened.
90 */
91static struct platform_device *st_get_plat_device(int id)
92{
93 return st_kim_devices[id];
94}
95
96/**
97 * validate_firmware_response -
98 * function to return whether the firmware response was proper
99 * in case of error don't complete so that waiting for proper
100 * response times out
101 */
102void validate_firmware_response(struct kim_data_s *kim_gdata)
103{
104 struct sk_buff *skb = kim_gdata->rx_skb;
105 if (unlikely(skb->data[5] != 0)) {
106 pr_err("no proper response during fw download");
107 pr_err("data6 %x", skb->data[5]);
108 return; /* keep waiting for the proper response */
109 }
110 /* becos of all the script being downloaded */
111 complete_all(&kim_gdata->kim_rcvd);
112 kfree_skb(skb);
113}
114
115/* check for data len received inside kim_int_recv
116 * most often hit the last case to update state to waiting for data
117 */
118static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
119{
120 register int room = skb_tailroom(kim_gdata->rx_skb);
121
122 pr_debug("len %d room %d", len, room);
123
124 if (!len) {
125 validate_firmware_response(kim_gdata);
126 } else if (len > room) {
127 /* Received packet's payload length is larger.
128 * We can't accommodate it in created skb.
129 */
130 pr_err("Data length is too large len %d room %d", len,
131 room);
132 kfree_skb(kim_gdata->rx_skb);
133 } else {
134 /* Packet header has non-zero payload length and
135 * we have enough space in created skb. Lets read
136 * payload data */
137 kim_gdata->rx_state = ST_BT_W4_DATA;
138 kim_gdata->rx_count = len;
139 return len;
140 }
141
142 /* Change ST LL state to continue to process next
143 * packet */
144 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
145 kim_gdata->rx_skb = NULL;
146 kim_gdata->rx_count = 0;
147
148 return 0;
149}
150
151/**
152 * kim_int_recv - receive function called during firmware download
153 * firmware download responses on different UART drivers
154 * have been observed to come in bursts of different
155 * tty_receive and hence the logic
156 */
157void kim_int_recv(struct kim_data_s *kim_gdata,
158 const unsigned char *data, long count)
159{
160 register char *ptr;
161 struct hci_event_hdr *eh;
162 register int len = 0, type = 0;
163
164 pr_debug("%s", __func__);
165 /* Decode received bytes here */
166 ptr = (char *)data;
167 if (unlikely(ptr == NULL)) {
168 pr_err(" received null from TTY ");
169 return;
170 }
171 while (count) {
172 if (kim_gdata->rx_count) {
173 len = min_t(unsigned int, kim_gdata->rx_count, count);
174 memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len);
175 kim_gdata->rx_count -= len;
176 count -= len;
177 ptr += len;
178
179 if (kim_gdata->rx_count)
180 continue;
181
182 /* Check ST RX state machine , where are we? */
183 switch (kim_gdata->rx_state) {
184 /* Waiting for complete packet ? */
185 case ST_BT_W4_DATA:
186 pr_debug("Complete pkt received");
187 validate_firmware_response(kim_gdata);
188 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
189 kim_gdata->rx_skb = NULL;
190 continue;
191 /* Waiting for Bluetooth event header ? */
192 case ST_BT_W4_EVENT_HDR:
193 eh = (struct hci_event_hdr *)kim_gdata->
194 rx_skb->data;
195 pr_debug("Event header: evt 0x%2.2x"
196 "plen %d", eh->evt, eh->plen);
197 kim_check_data_len(kim_gdata, eh->plen);
198 continue;
199 } /* end of switch */
200 } /* end of if rx_state */
201 switch (*ptr) {
202 /* Bluetooth event packet? */
203 case HCI_EVENT_PKT:
204 pr_info("Event packet");
205 kim_gdata->rx_state = ST_BT_W4_EVENT_HDR;
206 kim_gdata->rx_count = HCI_EVENT_HDR_SIZE;
207 type = HCI_EVENT_PKT;
208 break;
209 default:
210 pr_info("unknown packet");
211 ptr++;
212 count--;
213 continue;
214 }
215 ptr++;
216 count--;
217 kim_gdata->rx_skb =
218 bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
219 if (!kim_gdata->rx_skb) {
220 pr_err("can't allocate mem for new packet");
221 kim_gdata->rx_state = ST_W4_PACKET_TYPE;
222 kim_gdata->rx_count = 0;
223 return;
224 }
225 bt_cb(kim_gdata->rx_skb)->pkt_type = type;
226 }
227 pr_info("done %s", __func__);
228 return;
229}
230
231static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
232{
233 unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0;
234 char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 };
235
236 pr_debug("%s", __func__);
237
238 INIT_COMPLETION(kim_gdata->kim_rcvd);
239 if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) {
240 pr_err("kim: couldn't write 4 bytes");
241 return -1;
242 }
243
244 if (!wait_for_completion_timeout
245 (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
246 pr_err(" waiting for ver info- timed out ");
247 return -1;
248 }
249
250 version =
251 MAKEWORD(kim_gdata->resp_buffer[13],
252 kim_gdata->resp_buffer[14]);
253 chip = (version & 0x7C00) >> 10;
254 min_ver = (version & 0x007F);
255 maj_ver = (version & 0x0380) >> 7;
256
257 if (version & 0x8000)
258 maj_ver |= 0x0008;
259
260 sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
261
262 /* to be accessed later via sysfs entry */
263 kim_gdata->version.full = version;
264 kim_gdata->version.chip = chip;
265 kim_gdata->version.maj_ver = maj_ver;
266 kim_gdata->version.min_ver = min_ver;
267
268 pr_info("%s", bts_scr_name);
269 return 0;
270}
271
272/**
273 * download_firmware -
274 * internal function which parses through the .bts firmware
275 * script file intreprets SEND, DELAY actions only as of now
276 */
277static long download_firmware(struct kim_data_s *kim_gdata)
278{
279 long err = 0;
280 long len = 0;
281 register unsigned char *ptr = NULL;
282 register unsigned char *action_ptr = NULL;
283 unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
284
285 err = read_local_version(kim_gdata, bts_scr_name);
286 if (err != 0) {
287 pr_err("kim: failed to read local ver");
288 return err;
289 }
290 err =
291 request_firmware(&kim_gdata->fw_entry, bts_scr_name,
292 &kim_gdata->kim_pdev->dev);
293 if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) ||
294 (kim_gdata->fw_entry->size == 0))) {
295 pr_err(" request_firmware failed(errno %ld) for %s", err,
296 bts_scr_name);
297 return -1;
298 }
299 ptr = (void *)kim_gdata->fw_entry->data;
300 len = kim_gdata->fw_entry->size;
301 /* bts_header to remove out magic number and
302 * version
303 */
304 ptr += sizeof(struct bts_header);
305 len -= sizeof(struct bts_header);
306
307 while (len > 0 && ptr) {
308 pr_debug(" action size %d, type %d ",
309 ((struct bts_action *)ptr)->size,
310 ((struct bts_action *)ptr)->type);
311
312 switch (((struct bts_action *)ptr)->type) {
313 case ACTION_SEND_COMMAND: /* action send */
314 action_ptr = &(((struct bts_action *)ptr)->data[0]);
315 if (unlikely
316 (((struct hci_command *)action_ptr)->opcode ==
317 0xFF36)) {
318 /* ignore remote change
319 * baud rate HCI VS command */
320 pr_err
321 (" change remote baud"
322 " rate command in firmware");
323 break;
324 }
325
326 INIT_COMPLETION(kim_gdata->kim_rcvd);
327 err = st_int_write(kim_gdata->core_data,
328 ((struct bts_action_send *)action_ptr)->data,
329 ((struct bts_action *)ptr)->size);
330 if (unlikely(err < 0)) {
331 release_firmware(kim_gdata->fw_entry);
332 return -1;
333 }
334 if (!wait_for_completion_timeout
335 (&kim_gdata->kim_rcvd,
336 msecs_to_jiffies(CMD_RESP_TIME))) {
337 pr_err
338 (" response timeout during fw download ");
339 /* timed out */
340 release_firmware(kim_gdata->fw_entry);
341 return -1;
342 }
343 break;
344 case ACTION_DELAY: /* sleep */
345 pr_info("sleep command in scr");
346 action_ptr = &(((struct bts_action *)ptr)->data[0]);
347 mdelay(((struct bts_action_delay *)action_ptr)->msec);
348 break;
349 }
350 len =
351 len - (sizeof(struct bts_action) +
352 ((struct bts_action *)ptr)->size);
353 ptr =
354 ptr + sizeof(struct bts_action) +
355 ((struct bts_action *)ptr)->size;
356 }
357 /* fw download complete */
358 release_firmware(kim_gdata->fw_entry);
359 return 0;
360}
361
362/**********************************************************************/
363/* functions called from ST core */
364/* function to toggle the GPIO
365 * needs to know whether the GPIO is active high or active low
366 */
367void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
368{
369 struct platform_device *kim_pdev;
370 struct kim_data_s *kim_gdata;
371 pr_info(" %s ", __func__);
372
373 kim_pdev = st_get_plat_device(0);
374 kim_gdata = dev_get_drvdata(&kim_pdev->dev);
375
376 if (kim_gdata->gpios[type] == -1) {
377 pr_info(" gpio not requested for protocol %s",
378 protocol_names[type]);
379 return;
380 }
381 switch (type) {
382 case ST_BT:
383 /*Do Nothing */
384 break;
385
386 case ST_FM:
387 if (state == KIM_GPIO_ACTIVE)
388 gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_LOW);
389 else
390 gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_HIGH);
391 break;
392
393 case ST_GPS:
394 if (state == KIM_GPIO_ACTIVE)
395 gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_HIGH);
396 else
397 gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW);
398 break;
399
400 case ST_MAX:
401 default:
402 break;
403 }
404
405 return;
406}
407
408/* called from ST Core, when REG_IN_PROGRESS (registration in progress)
409 * can be because of
410 * 1. response to read local version
411 * 2. during send/recv's of firmware download
412 */
413void st_kim_recv(void *disc_data, const unsigned char *data, long count)
414{
415 struct st_data_s *st_gdata = (struct st_data_s *)disc_data;
416 struct kim_data_s *kim_gdata = st_gdata->kim_data;
417
418 pr_info(" %s ", __func__);
419 /* copy to local buffer */
420 if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
421 /* must be the read_ver_cmd */
422 memcpy(kim_gdata->resp_buffer, data, count);
423 complete_all(&kim_gdata->kim_rcvd);
424 return;
425 } else {
426 kim_int_recv(kim_gdata, data, count);
427 /* either completes or times out */
428 }
429 return;
430}
431
432/* to signal completion of line discipline installation
433 * called from ST Core, upon tty_open
434 */
435void st_kim_complete(void *kim_data)
436{
437 struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
438 complete(&kim_gdata->ldisc_installed);
439}
440
441/**
442 * st_kim_start - called from ST Core upon 1st registration
443 * This involves toggling the chip enable gpio, reading
444 * the firmware version from chip, forming the fw file name
445 * based on the chip version, requesting the fw, parsing it
446 * and perform download(send/recv).
447 */
448long st_kim_start(void *kim_data)
449{
450 long err = 0;
451 long retry = POR_RETRY_COUNT;
452 struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
453
454 pr_info(" %s", __func__);
455
456 do {
457 /* TODO: this is only because rfkill sub-system
458 * doesn't send events to user-space if the state
459 * isn't changed
460 */
461 rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
462 /* Configure BT nShutdown to HIGH state */
463 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
464 mdelay(5); /* FIXME: a proper toggle */
465 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH);
466 mdelay(100);
467 /* re-initialize the completion */
468 INIT_COMPLETION(kim_gdata->ldisc_installed);
469#if 0 /* older way of signalling user-space UIM */
470 /* send signal to UIM */
471 err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 0);
472 if (err != 0) {
473 pr_info(" sending SIGUSR2 to uim failed %ld", err);
474 err = -1;
475 continue;
476 }
477#endif
478 /* unblock and send event to UIM via /dev/rfkill */
479 rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 0);
480 /* wait for ldisc to be installed */
481 err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
482 msecs_to_jiffies(LDISC_TIME));
483 if (!err) { /* timeout */
484 pr_err("line disc installation timed out ");
485 err = -1;
486 continue;
487 } else {
488 /* ldisc installed now */
489 pr_info(" line discipline installed ");
490 err = download_firmware(kim_gdata);
491 if (err != 0) {
492 pr_err("download firmware failed");
493 continue;
494 } else { /* on success don't retry */
495 break;
496 }
497 }
498 } while (retry--);
499 return err;
500}
501
502/**
503 * st_kim_stop - called from ST Core, on the last un-registration
504 * toggle low the chip enable gpio
505 */
506long st_kim_stop(void *kim_data)
507{
508 long err = 0;
509 struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
510
511 INIT_COMPLETION(kim_gdata->ldisc_installed);
512#if 0 /* older way of signalling user-space UIM */
513 /* send signal to UIM */
514 err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 1);
515 if (err != 0) {
516 pr_err("sending SIGUSR2 to uim failed %ld", err);
517 return -1;
518 }
519#endif
520 /* set BT rfkill to be blocked */
521 err = rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1);
522
523 /* wait for ldisc to be un-installed */
524 err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
525 msecs_to_jiffies(LDISC_TIME));
526 if (!err) { /* timeout */
527 pr_err(" timed out waiting for ldisc to be un-installed");
528 return -1;
529 }
530
531 /* By default configure BT nShutdown to LOW state */
532 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
533 mdelay(1);
534 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH);
535 mdelay(1);
536 gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW);
537 return err;
538}
539
540/**********************************************************************/
541/* functions called from subsystems */
542/* called when debugfs entry is read from */
543
544static int show_version(struct seq_file *s, void *unused)
545{
546 struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
547 seq_printf(s, "%04X %d.%d.%d\n", kim_gdata->version.full,
548 kim_gdata->version.chip, kim_gdata->version.maj_ver,
549 kim_gdata->version.min_ver);
550 return 0;
551}
552
553static int show_list(struct seq_file *s, void *unused)
554{
555 struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
556 kim_st_list_protocols(kim_gdata->core_data, s);
557 return 0;
558}
559
560/* function called from rfkill subsystem, when someone from
561 * user space would write 0/1 on the sysfs entry
562 * /sys/class/rfkill/rfkill0,1,3/state
563 */
564static int kim_toggle_radio(void *data, bool blocked)
565{
566 enum proto_type type = *((enum proto_type *)data);
567 pr_debug(" %s: %d ", __func__, type);
568
569 switch (type) {
570 case ST_BT:
571 /* do nothing */
572 break;
573 case ST_FM:
574 case ST_GPS:
575 if (blocked)
576 st_kim_chip_toggle(type, KIM_GPIO_INACTIVE);
577 else
578 st_kim_chip_toggle(type, KIM_GPIO_ACTIVE);
579 break;
580 case ST_MAX:
581 pr_err(" wrong proto type ");
582 break;
583 }
584 return 0;
585}
586
587/**
588 * st_kim_ref - reference the core's data
589 * This references the per-ST platform device in the arch/xx/
590 * board-xx.c file.
591 * This would enable multiple such platform devices to exist
592 * on a given platform
593 */
594void st_kim_ref(struct st_data_s **core_data, int id)
595{
596 struct platform_device *pdev;
597 struct kim_data_s *kim_gdata;
598 /* get kim_gdata reference from platform device */
599 pdev = st_get_plat_device(id);
600 kim_gdata = dev_get_drvdata(&pdev->dev);
601 *core_data = kim_gdata->core_data;
602}
603
604static int kim_version_open(struct inode *i, struct file *f)
605{
606 return single_open(f, show_version, i->i_private);
607}
608
609static int kim_list_open(struct inode *i, struct file *f)
610{
611 return single_open(f, show_list, i->i_private);
612}
613
614static const struct file_operations version_debugfs_fops = {
615 /* version info */
616 .open = kim_version_open,
617 .read = seq_read,
618 .llseek = seq_lseek,
619 .release = single_release,
620};
621static const struct file_operations list_debugfs_fops = {
622 /* protocols info */
623 .open = kim_list_open,
624 .read = seq_read,
625 .llseek = seq_lseek,
626 .release = single_release,
627};
628
629/**********************************************************************/
630/* functions called from platform device driver subsystem
631 * need to have a relevant platform device entry in the platform's
632 * board-*.c file
633 */
634
635struct dentry *kim_debugfs_dir;
636static int kim_probe(struct platform_device *pdev)
637{
638 long status;
639 long proto;
640 long *gpios = pdev->dev.platform_data;
641 struct kim_data_s *kim_gdata;
642
643 if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
644 /* multiple devices could exist */
645 st_kim_devices[pdev->id] = pdev;
646 } else {
647 /* platform's sure about existance of 1 device */
648 st_kim_devices[0] = pdev;
649 }
650
651 kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
652 if (!kim_gdata) {
653 pr_err("no mem to allocate");
654 return -ENOMEM;
655 }
656 dev_set_drvdata(&pdev->dev, kim_gdata);
657
658 status = st_core_init(&kim_gdata->core_data);
659 if (status != 0) {
660 pr_err(" ST core init failed");
661 return -1;
662 }
663 /* refer to itself */
664 kim_gdata->core_data->kim_data = kim_gdata;
665
666 for (proto = 0; proto < ST_MAX; proto++) {
667 kim_gdata->gpios[proto] = gpios[proto];
668 pr_info(" %ld gpio to be requested", gpios[proto]);
669 }
670
671 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
672 /* Claim the Bluetooth/FM/GPIO
673 * nShutdown gpio from the system
674 */
675 status = gpio_request(gpios[proto], "kim");
676 if (unlikely(status)) {
677 pr_err(" gpio %ld request failed ", gpios[proto]);
678 proto -= 1;
679 while (proto >= 0) {
680 if (gpios[proto] != -1)
681 gpio_free(gpios[proto]);
682 }
683 return status;
684 }
685
686 /* Configure nShutdown GPIO as output=0 */
687 status =
688 gpio_direction_output(gpios[proto], 0);
689 if (unlikely(status)) {
690 pr_err(" unable to configure gpio %ld",
691 gpios[proto]);
692 proto -= 1;
693 while (proto >= 0) {
694 if (gpios[proto] != -1)
695 gpio_free(gpios[proto]);
696 }
697 return status;
698 }
699 }
700 /* get reference of pdev for request_firmware
701 */
702 kim_gdata->kim_pdev = pdev;
703 init_completion(&kim_gdata->kim_rcvd);
704 init_completion(&kim_gdata->ldisc_installed);
705
706 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
707 /* TODO: should all types be rfkill_type_bt ? */
708 kim_gdata->rf_protos[proto] = proto;
709 kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto],
710 &pdev->dev, RFKILL_TYPE_BLUETOOTH,
711 &kim_rfkill_ops, &kim_gdata->rf_protos[proto]);
712 if (kim_gdata->rfkill[proto] == NULL) {
713 pr_err("cannot create rfkill entry for gpio %ld",
714 gpios[proto]);
715 continue;
716 }
717 /* block upon creation */
718 rfkill_init_sw_state(kim_gdata->rfkill[proto], 1);
719 status = rfkill_register(kim_gdata->rfkill[proto]);
720 if (unlikely(status)) {
721 pr_err("rfkill registration failed for gpio %ld",
722 gpios[proto]);
723 rfkill_unregister(kim_gdata->rfkill[proto]);
724 continue;
725 }
726 pr_info("rfkill entry created for %ld", gpios[proto]);
727 }
728
729 kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
730 if (IS_ERR(kim_debugfs_dir)) {
731 pr_err(" debugfs entries creation failed ");
732 kim_debugfs_dir = NULL;
733 return -1;
734 }
735
736 debugfs_create_file("version", S_IRUGO, kim_debugfs_dir,
737 kim_gdata, &version_debugfs_fops);
738 debugfs_create_file("protocols", S_IRUGO, kim_debugfs_dir,
739 kim_gdata, &list_debugfs_fops);
740 pr_info(" debugfs entries created ");
741 return 0;
742}
743
744static int kim_remove(struct platform_device *pdev)
745{
746 /* free the GPIOs requested
747 */
748 long *gpios = pdev->dev.platform_data;
749 long proto;
750 struct kim_data_s *kim_gdata;
751
752 kim_gdata = dev_get_drvdata(&pdev->dev);
753
754 for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) {
755 /* Claim the Bluetooth/FM/GPIO
756 * nShutdown gpio from the system
757 */
758 gpio_free(gpios[proto]);
759 rfkill_unregister(kim_gdata->rfkill[proto]);
760 rfkill_destroy(kim_gdata->rfkill[proto]);
761 kim_gdata->rfkill[proto] = NULL;
762 }
763 pr_info("kim: GPIO Freed");
764 debugfs_remove_recursive(kim_debugfs_dir);
765 kim_gdata->kim_pdev = NULL;
766 st_core_exit(kim_gdata->core_data);
767
768 kfree(kim_gdata);
769 kim_gdata = NULL;
770 return 0;
771}
772
773/**********************************************************************/
774/* entry point for ST KIM module, called in from ST Core */
775
776static int __init st_kim_init(void)
777{
778 long ret = 0;
779 ret = platform_driver_register(&kim_platform_driver);
780 if (ret != 0) {
781 pr_err("platform drv registration failed");
782 return -1;
783 }
784 return 0;
785}
786
787static void __exit st_kim_deinit(void)
788{
789 /* the following returns void */
790 platform_driver_unregister(&kim_platform_driver);
791}
792
793
794module_init(st_kim_init);
795module_exit(st_kim_deinit);
796MODULE_AUTHOR("Pavan Savoy <pavan_savoy@ti.com>");
797MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips ");
798MODULE_LICENSE("GPL");