xref: /btstack/port/raspi/btstack_control_raspi.c (revision 11e995b1e9158c6603183124284d69f415ce5822)
1 #include "btstack_control.h"
2 #include "btstack_debug.h"
3 
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <sys/ioctl.h>
9 
10 // constansts for firmware interface
11 #define RPI_FIRMWARE_DEV "/dev/vcio"
12 #define IOCTL_RPI_FIRMWARE_PROPERTY _IOWR(100, 0, char*)
13 
14 // firmware request messages
15 #define RPI_FIRMWARE_STATUS_REQUEST (0)
16 #define RPI_FIRMWARE_PROPERTY_END   (0)
17 #define RPI_FIRMWARE_SET_GPIO_STATE (0x00038041)
18 
19 // results
20 #define RPI_FIRMWARE_STATUS_SUCCESS (0x80000000)
21 #define RPI_FIRMWARE_STATUS_ERROR   (0x80000001)
22 
23 // BCM4343 power management pins on main CPU
24 #define BT_REG_ON   (128)
25 #define WL_REG_ON   (129)
26 
27 // fd for firmware interface
28 static int fd = -1;
29 
30 static void raspi_gpio_set(int gpio, int state){
31 	uint32_t m[8];
32 	m[0] = sizeof(m); // total len in bytes
33 	m[1] = RPI_FIRMWARE_STATUS_REQUEST;
34 	m[2] = RPI_FIRMWARE_SET_GPIO_STATE;
35 	m[3] = 8;		  // request size in bytes
36 	m[4] = 0; 		  // request response size
37 	m[5] = gpio;
38 	m[6] = state ? 1 : 0;
39 	m[7] = RPI_FIRMWARE_PROPERTY_END;;
40 
41 	int ioctl_result = ioctl(fd, IOCTL_RPI_FIRMWARE_PROPERTY, m);
42 	if (ioctl_result == -1) {
43 		log_error("ioctl: IOCTL_RPI_FIRMWARE_PROPERTY: %s", strerror(errno));
44 		return;
45 	}
46 
47 	uint32_t result = m[1];
48 	if (result != RPI_FIRMWARE_STATUS_SUCCESS) {
49 		log_error("ioctl: firmware result 0x%08x\n", result);
50 	}
51 }
52 
53 static void raspi_init (const void *config) {
54 	UNUSED(config);
55 
56 	fd = open(RPI_FIRMWARE_DEV, O_NONBLOCK);
57 	if (fd == -1) {
58 		log_error("cannot open: %s: %s", RPI_FIRMWARE_DEV, strerror(errno));
59 		return;
60 	}
61 }
62 
63 static int raspi_on (){
64     log_info("raspi_on");
65     raspi_gpio_set( BT_REG_ON, 1 );
66     return 0;
67 }
68 
69 static int raspi_off(void){
70     log_info("raspi_off");
71     raspi_gpio_set( BT_REG_ON, 0 );
72     return 0;
73 }
74 
75 static btstack_control_t control = {
76     raspi_init,
77     raspi_on,
78     raspi_off,
79     NULL,
80     NULL,
81     NULL
82 };
83 
84 btstack_control_t *btstack_control_raspi_get_instance(){
85     return &control;
86 }
87