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