init_stlc2500.c revision 1.1 1 1.1 plunky /* $NetBSD: init_stlc2500.c,v 1.1 2008/04/15 11:17:48 plunky Exp $ */
2 1.1 plunky
3 1.1 plunky /*-
4 1.1 plunky * Copyright (c) 2008 Iain Hibbert
5 1.1 plunky * All rights reserved.
6 1.1 plunky *
7 1.1 plunky * Redistribution and use in source and binary forms, with or without
8 1.1 plunky * modification, are permitted provided that the following conditions
9 1.1 plunky * are met:
10 1.1 plunky * 1. Redistributions of source code must retain the above copyright
11 1.1 plunky * notice, this list of conditions and the following disclaimer.
12 1.1 plunky * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 plunky * notice, this list of conditions and the following disclaimer in the
14 1.1 plunky * documentation and/or other materials provided with the distribution.
15 1.1 plunky *
16 1.1 plunky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 plunky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 plunky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 plunky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 plunky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.1 plunky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.1 plunky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.1 plunky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.1 plunky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.1 plunky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1 plunky */
27 1.1 plunky
28 1.1 plunky /*
29 1.1 plunky * init information in this file gleaned from hciattach(8)
30 1.1 plunky * command from BlueZ for Linux - see http://www.bluez.org/
31 1.1 plunky */
32 1.1 plunky
33 1.1 plunky #include <sys/cdefs.h>
34 1.1 plunky __RCSID("$NetBSD: init_stlc2500.c,v 1.1 2008/04/15 11:17:48 plunky Exp $");
35 1.1 plunky
36 1.1 plunky #include <bluetooth.h>
37 1.1 plunky #include <err.h>
38 1.1 plunky #include <errno.h>
39 1.1 plunky #include <fcntl.h>
40 1.1 plunky #include <stdlib.h>
41 1.1 plunky #include <termios.h>
42 1.1 plunky #include <unistd.h>
43 1.1 plunky
44 1.1 plunky #include "btattach.h"
45 1.1 plunky
46 1.1 plunky #define HCI_CMD_ERICSSON_READ_REVISION_INFO \
47 1.1 plunky HCI_OPCODE(HCI_OGF_VENDOR, 0x00f)
48 1.1 plunky
49 1.1 plunky #define HCI_CMD_ST_STORE_IN_NVDS \
50 1.1 plunky HCI_OPCODE(HCI_OGF_VENDOR, 0x022)
51 1.1 plunky
52 1.1 plunky typedef struct {
53 1.1 plunky uint8_t d0; /* ? */
54 1.1 plunky uint8_t d1; /* ? */
55 1.1 plunky bdaddr_t bdaddr;
56 1.1 plunky } __attribute__ ((__packed__)) hci_store_in_nvds_cp;
57 1.1 plunky
58 1.1 plunky static const char *default_bdaddr = "00:80:e1:00:ab:ba";
59 1.1 plunky
60 1.1 plunky #define HCI_CMD_ST_LOAD_FIRMWARE \
61 1.1 plunky HCI_OPCODE(HCI_OGF_VENDOR, 0x02e)
62 1.1 plunky
63 1.1 plunky static int
64 1.1 plunky firmload_stlc2500(int fd, uint16_t revision, const char *ext)
65 1.1 plunky {
66 1.1 plunky uint8_t buf[0x100], seq;
67 1.1 plunky char *name;
68 1.1 plunky ssize_t n;
69 1.1 plunky int ff;
70 1.1 plunky
71 1.1 plunky /* we should look up hw.firmware.path and search for the file */
72 1.1 plunky
73 1.1 plunky asprintf(&name, "STLC2500_R%d_%02d_%s", (revision & 0xff), (revision >> 8), ext);
74 1.1 plunky ff = open(name, O_RDONLY, 0);
75 1.1 plunky if (ff < 0) {
76 1.1 plunky if (errno != ENOENT)
77 1.1 plunky err(EXIT_FAILURE, "%s", name);
78 1.1 plunky
79 1.1 plunky free(name);
80 1.1 plunky return -1;
81 1.1 plunky }
82 1.1 plunky
83 1.1 plunky for (seq = 0;; seq++) {
84 1.1 plunky n = read(ff, buf + 1, sizeof(buf) - 1);
85 1.1 plunky if (n < 0)
86 1.1 plunky err(EXIT_FAILURE, "%s", name);
87 1.1 plunky
88 1.1 plunky if (n == 0)
89 1.1 plunky break;
90 1.1 plunky
91 1.1 plunky buf[0] = seq;
92 1.1 plunky uart_send_cmd(fd, HCI_CMD_ST_LOAD_FIRMWARE, buf, (size_t)(n + 1));
93 1.1 plunky n = uart_recv_cc(fd, HCI_CMD_ST_LOAD_FIRMWARE, buf, 1);
94 1.1 plunky /* command complete ok? */
95 1.1 plunky
96 1.1 plunky if (n != 1 || buf[0] != seq)
97 1.1 plunky err(EXIT_FAILURE, "sequence mismatch");
98 1.1 plunky }
99 1.1 plunky
100 1.1 plunky close(ff);
101 1.1 plunky free(name);
102 1.1 plunky return 0;
103 1.1 plunky }
104 1.1 plunky
105 1.1 plunky void
106 1.1 plunky init_stlc2500(int fd, unsigned int speed)
107 1.1 plunky {
108 1.1 plunky hci_read_local_ver_rp rp;
109 1.1 plunky hci_store_in_nvds_cp cp;
110 1.1 plunky struct termios tio;
111 1.1 plunky int n;
112 1.1 plunky
113 1.1 plunky /* STLC2500 has an ericsson core */
114 1.1 plunky init_ericsson(fd, speed);
115 1.1 plunky
116 1.1 plunky tcgetattr(fd, &tio);
117 1.1 plunky cfsetspeed(&tio, speed);
118 1.1 plunky tcsetattr(fd, TCSANOW, &tio);
119 1.1 plunky
120 1.1 plunky uart_send_cmd(fd, HCI_CMD_READ_LOCAL_VER, NULL, 0);
121 1.1 plunky n = uart_recv_cc(fd, HCI_CMD_READ_LOCAL_VER, &rp, sizeof(rp));
122 1.1 plunky if (n != sizeof(rp) || rp.status != 0x00)
123 1.1 plunky errx(EXIT_FAILURE, "read local version command failed");
124 1.1 plunky
125 1.1 plunky if (firmload_stlc2500(fd, rp.hci_revision, "ptc") < 0)
126 1.1 plunky warn("no ROM patch file");
127 1.1 plunky
128 1.1 plunky if (firmload_stlc2500(fd, rp.hci_revision, "ssf") < 0)
129 1.1 plunky warn("no static settings file");
130 1.1 plunky
131 1.1 plunky cp.d0 = 0xfe; /* ? */
132 1.1 plunky cp.d1 = 0x06; /* ? */
133 1.1 plunky bt_aton(default_bdaddr, &cp.bdaddr);
134 1.1 plunky
135 1.1 plunky uart_send_cmd(fd, HCI_CMD_ST_STORE_IN_NVDS, &cp, sizeof(cp));
136 1.1 plunky uart_recv_cc(fd, HCI_CMD_ST_STORE_IN_NVDS, NULL, 0);
137 1.1 plunky /* command complete ok? */
138 1.1 plunky /* assume it succeeded? */
139 1.1 plunky
140 1.1 plunky uart_send_cmd(fd, HCI_CMD_RESET, NULL, 0);
141 1.1 plunky uart_recv_cc(fd, HCI_CMD_RESET, NULL, 0);
142 1.1 plunky /* assume it succeeded? */
143 1.1 plunky }
144