xref: /btstack/port/raspi/btstack_control_raspi.c (revision 2c4f9bbb6d93b3f1a90ed62ac67e4cd019f0736a)
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 static uint8_t bt_reg_en;
24 
25 void btstack_control_raspi_set_bt_reg_en_pin(uint8_t bt_reg_en_pin){
26 	bt_reg_en = bt_reg_en_pin;
27 }
28 
29 // fd for firmware interface
30 static int fd = -1;
31 
32 static void raspi_gpio_set(int gpio, int state){
33 	uint32_t m[8];
34 	m[0] = sizeof(m); // total len in bytes
35 	m[1] = RPI_FIRMWARE_STATUS_REQUEST;
36 	m[2] = RPI_FIRMWARE_SET_GPIO_STATE;
37 	m[3] = 8;		  // request size in bytes
38 	m[4] = 0; 		  // request response size
39 	m[5] = gpio;
40 	m[6] = state ? 1 : 0;
41 	m[7] = RPI_FIRMWARE_PROPERTY_END;;
42 
43 	int ioctl_result = ioctl(fd, IOCTL_RPI_FIRMWARE_PROPERTY, m);
44 	if (ioctl_result == -1) {
45 		log_error("ioctl: IOCTL_RPI_FIRMWARE_PROPERTY: %s", strerror(errno));
46 		return;
47 	}
48 
49 	uint32_t result = m[1];
50 	if (result != RPI_FIRMWARE_STATUS_SUCCESS) {
51 		log_error("ioctl: firmware result 0x%08x\n", result);
52 	}
53 }
54 
55 static void raspi_init (const void *config) {
56 	UNUSED(config);
57 
58 	fd = open(RPI_FIRMWARE_DEV, O_NONBLOCK);
59 	if (fd == -1) {
60 		log_error("cannot open: %s: %s", RPI_FIRMWARE_DEV, strerror(errno));
61 		return;
62 	}
63 }
64 
65 static int raspi_on (){
66     log_info("raspi_on");
67     raspi_gpio_set( bt_reg_en, 1 );
68     return 0;
69 }
70 
71 static int raspi_off(void){
72     log_info("raspi_off");
73     raspi_gpio_set( bt_reg_en, 0 );
74     return 0;
75 }
76 
77 static btstack_control_t control = {
78     raspi_init,
79     raspi_on,
80     raspi_off,
81     NULL,
82     NULL,
83     NULL
84 };
85 
86 btstack_control_t *btstack_control_raspi_get_instance(){
87     return &control;
88 }
89