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