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
btstack_control_raspi_set_bt_reg_en_pin(uint8_t bt_reg_en_pin)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
raspi_gpio_set(int gpio,int state)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
raspi_init(const void * config)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
raspi_on()65 static int raspi_on (){
66 log_info("raspi_on");
67 raspi_gpio_set( bt_reg_en, 1 );
68 return 0;
69 }
70
raspi_off(void)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
btstack_control_raspi_get_instance()86 btstack_control_t *btstack_control_raspi_get_instance(){
87 return &control;
88 }
89