1*15542a72SSheetal Tigadoli // SPDX-License-Identifier: BSD-2-Clause 2*15542a72SSheetal Tigadoli /* 3*15542a72SSheetal Tigadoli * Copyright 2019 Broadcom. 4*15542a72SSheetal Tigadoli */ 5*15542a72SSheetal Tigadoli 6*15542a72SSheetal Tigadoli #include <drivers/bcm_gpio.h> 7*15542a72SSheetal Tigadoli #include <io.h> 8*15542a72SSheetal Tigadoli #include <kernel/pseudo_ta.h> 9*15542a72SSheetal Tigadoli #include <trace.h> 10*15542a72SSheetal Tigadoli 11*15542a72SSheetal Tigadoli #define GPIO_SERVICE_UUID \ 12*15542a72SSheetal Tigadoli { 0x6272636D, 0x2018, 0x1101, \ 13*15542a72SSheetal Tigadoli { 0x42, 0x43, 0x4D, 0x5F, 0x47, 0x50, 0x49, 0x4F } } 14*15542a72SSheetal Tigadoli 15*15542a72SSheetal Tigadoli /* 16*15542a72SSheetal Tigadoli * Configure GPIO Pin 17*15542a72SSheetal Tigadoli * 18*15542a72SSheetal Tigadoli * [in] value[0].a: gpio pin number 19*15542a72SSheetal Tigadoli * [in] value[0].b: direction to configure 20*15542a72SSheetal Tigadoli */ 21*15542a72SSheetal Tigadoli #define PTA_BCM_GPIO_CMD_CFG 0 22*15542a72SSheetal Tigadoli 23*15542a72SSheetal Tigadoli /* 24*15542a72SSheetal Tigadoli * Set GPIO pin 25*15542a72SSheetal Tigadoli * 26*15542a72SSheetal Tigadoli * [in] value[0].a: gpio pin number 27*15542a72SSheetal Tigadoli * [in] value[0].b: value drive on pin 28*15542a72SSheetal Tigadoli */ 29*15542a72SSheetal Tigadoli #define PTA_BCM_GPIO_CMD_SET 1 30*15542a72SSheetal Tigadoli 31*15542a72SSheetal Tigadoli /* 32*15542a72SSheetal Tigadoli * Get GPIO pin 33*15542a72SSheetal Tigadoli * 34*15542a72SSheetal Tigadoli * [in] value[0].a: gpio pin number 35*15542a72SSheetal Tigadoli * [out] value[1].a: value read from gpio pin 36*15542a72SSheetal Tigadoli */ 37*15542a72SSheetal Tigadoli #define PTA_BCM_GPIO_CMD_GET 2 38*15542a72SSheetal Tigadoli 39*15542a72SSheetal Tigadoli #define GPIO_TA_NAME "pta_bcm_gpio.ta" 40*15542a72SSheetal Tigadoli 41*15542a72SSheetal Tigadoli static TEE_Result pta_gpio_config(uint32_t param_types, 42*15542a72SSheetal Tigadoli TEE_Param params[TEE_NUM_PARAMS]) 43*15542a72SSheetal Tigadoli { 44*15542a72SSheetal Tigadoli uint32_t gpio_num = 0; 45*15542a72SSheetal Tigadoli struct bcm_gpio_chip *bcm_gc = NULL; 46*15542a72SSheetal Tigadoli struct gpio_chip *gc = NULL; 47*15542a72SSheetal Tigadoli bool dir = false; 48*15542a72SSheetal Tigadoli TEE_Result res = TEE_SUCCESS; 49*15542a72SSheetal Tigadoli uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 50*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE, 51*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE, 52*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE); 53*15542a72SSheetal Tigadoli 54*15542a72SSheetal Tigadoli if (exp_param_types != param_types) { 55*15542a72SSheetal Tigadoli EMSG("Invalid Param types"); 56*15542a72SSheetal Tigadoli return TEE_ERROR_BAD_PARAMETERS; 57*15542a72SSheetal Tigadoli } 58*15542a72SSheetal Tigadoli 59*15542a72SSheetal Tigadoli gpio_num = params[0].value.a; 60*15542a72SSheetal Tigadoli dir = params[0].value.b; 61*15542a72SSheetal Tigadoli 62*15542a72SSheetal Tigadoli bcm_gc = bcm_gpio_pin_to_chip(gpio_num); 63*15542a72SSheetal Tigadoli if (!bcm_gc) { 64*15542a72SSheetal Tigadoli EMSG("GPIO %u not supported", gpio_num); 65*15542a72SSheetal Tigadoli return TEE_ERROR_NOT_SUPPORTED; 66*15542a72SSheetal Tigadoli } 67*15542a72SSheetal Tigadoli 68*15542a72SSheetal Tigadoli gc = &bcm_gc->chip; 69*15542a72SSheetal Tigadoli 70*15542a72SSheetal Tigadoli /* Make gpio secure. */ 71*15542a72SSheetal Tigadoli iproc_gpio_set_secure(gpio_num); 72*15542a72SSheetal Tigadoli 73*15542a72SSheetal Tigadoli if (dir) { 74*15542a72SSheetal Tigadoli /* Set GPIO to output with default value to 0 */ 75*15542a72SSheetal Tigadoli gc->ops->set_direction(gpio_num, GPIO_DIR_OUT); 76*15542a72SSheetal Tigadoli gc->ops->set_value(gpio_num, 0); 77*15542a72SSheetal Tigadoli } else { 78*15542a72SSheetal Tigadoli gc->ops->set_direction(gpio_num, GPIO_DIR_IN); 79*15542a72SSheetal Tigadoli } 80*15542a72SSheetal Tigadoli 81*15542a72SSheetal Tigadoli return res; 82*15542a72SSheetal Tigadoli } 83*15542a72SSheetal Tigadoli 84*15542a72SSheetal Tigadoli static TEE_Result pta_gpio_set(uint32_t param_types, 85*15542a72SSheetal Tigadoli TEE_Param params[TEE_NUM_PARAMS]) 86*15542a72SSheetal Tigadoli { 87*15542a72SSheetal Tigadoli uint32_t gpio_num = 0; 88*15542a72SSheetal Tigadoli uint32_t val = 0; 89*15542a72SSheetal Tigadoli TEE_Result res = TEE_SUCCESS; 90*15542a72SSheetal Tigadoli struct bcm_gpio_chip *bcm_gc = NULL; 91*15542a72SSheetal Tigadoli struct gpio_chip *gc = NULL; 92*15542a72SSheetal Tigadoli uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 93*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE, 94*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE, 95*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE); 96*15542a72SSheetal Tigadoli 97*15542a72SSheetal Tigadoli if (exp_param_types != param_types) { 98*15542a72SSheetal Tigadoli EMSG("Invalid Param types"); 99*15542a72SSheetal Tigadoli return TEE_ERROR_BAD_PARAMETERS; 100*15542a72SSheetal Tigadoli } 101*15542a72SSheetal Tigadoli 102*15542a72SSheetal Tigadoli gpio_num = params[0].value.a; 103*15542a72SSheetal Tigadoli val = !!params[0].value.b; 104*15542a72SSheetal Tigadoli 105*15542a72SSheetal Tigadoli bcm_gc = bcm_gpio_pin_to_chip(gpio_num); 106*15542a72SSheetal Tigadoli if (!bcm_gc) { 107*15542a72SSheetal Tigadoli EMSG("GPIO %u not supported", gpio_num); 108*15542a72SSheetal Tigadoli return TEE_ERROR_NOT_SUPPORTED; 109*15542a72SSheetal Tigadoli } 110*15542a72SSheetal Tigadoli 111*15542a72SSheetal Tigadoli gc = &bcm_gc->chip; 112*15542a72SSheetal Tigadoli 113*15542a72SSheetal Tigadoli /* 114*15542a72SSheetal Tigadoli * For setting a value to GPIO Pin, 115*15542a72SSheetal Tigadoli * need to make sure the PIN is configured in 116*15542a72SSheetal Tigadoli * output direction. 117*15542a72SSheetal Tigadoli */ 118*15542a72SSheetal Tigadoli if (gc->ops->get_direction(gpio_num) != GPIO_DIR_OUT) { 119*15542a72SSheetal Tigadoli EMSG("gpio pin %u is configured as INPUT", gpio_num); 120*15542a72SSheetal Tigadoli return TEE_ERROR_ACCESS_DENIED; 121*15542a72SSheetal Tigadoli } 122*15542a72SSheetal Tigadoli 123*15542a72SSheetal Tigadoli gc->ops->set_value(gpio_num, val); 124*15542a72SSheetal Tigadoli 125*15542a72SSheetal Tigadoli DMSG("GPIO(%d) value = 0x%08x", gpio_num, gc->ops->get_value(gpio_num)); 126*15542a72SSheetal Tigadoli 127*15542a72SSheetal Tigadoli return res; 128*15542a72SSheetal Tigadoli } 129*15542a72SSheetal Tigadoli 130*15542a72SSheetal Tigadoli static TEE_Result pta_gpio_get(uint32_t param_types, 131*15542a72SSheetal Tigadoli TEE_Param params[TEE_NUM_PARAMS]) 132*15542a72SSheetal Tigadoli { 133*15542a72SSheetal Tigadoli uint32_t gpio_num = 0; 134*15542a72SSheetal Tigadoli struct bcm_gpio_chip *bcm_gc = NULL; 135*15542a72SSheetal Tigadoli struct gpio_chip *gc = NULL; 136*15542a72SSheetal Tigadoli uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 137*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_VALUE_OUTPUT, 138*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE, 139*15542a72SSheetal Tigadoli TEE_PARAM_TYPE_NONE); 140*15542a72SSheetal Tigadoli 141*15542a72SSheetal Tigadoli if (exp_param_types != param_types) { 142*15542a72SSheetal Tigadoli EMSG("Invalid Param types"); 143*15542a72SSheetal Tigadoli return TEE_ERROR_BAD_PARAMETERS; 144*15542a72SSheetal Tigadoli } 145*15542a72SSheetal Tigadoli 146*15542a72SSheetal Tigadoli gpio_num = params[0].value.a; 147*15542a72SSheetal Tigadoli 148*15542a72SSheetal Tigadoli bcm_gc = bcm_gpio_pin_to_chip(gpio_num); 149*15542a72SSheetal Tigadoli if (!bcm_gc) { 150*15542a72SSheetal Tigadoli EMSG("GPIO %u not supported", gpio_num); 151*15542a72SSheetal Tigadoli return TEE_ERROR_NOT_SUPPORTED; 152*15542a72SSheetal Tigadoli } 153*15542a72SSheetal Tigadoli 154*15542a72SSheetal Tigadoli gc = &bcm_gc->chip; 155*15542a72SSheetal Tigadoli 156*15542a72SSheetal Tigadoli params[1].value.a = gc->ops->get_value(gpio_num); 157*15542a72SSheetal Tigadoli 158*15542a72SSheetal Tigadoli DMSG("gpio(%d) value = 0x%08x", gpio_num, params[1].value.a); 159*15542a72SSheetal Tigadoli 160*15542a72SSheetal Tigadoli return TEE_SUCCESS; 161*15542a72SSheetal Tigadoli } 162*15542a72SSheetal Tigadoli 163*15542a72SSheetal Tigadoli static TEE_Result invoke_command(void *session_context __unused, 164*15542a72SSheetal Tigadoli uint32_t cmd_id, 165*15542a72SSheetal Tigadoli uint32_t param_types, 166*15542a72SSheetal Tigadoli TEE_Param params[TEE_NUM_PARAMS]) 167*15542a72SSheetal Tigadoli { 168*15542a72SSheetal Tigadoli TEE_Result res = TEE_SUCCESS; 169*15542a72SSheetal Tigadoli 170*15542a72SSheetal Tigadoli DMSG("command entry point[%d] for \"%s\"", cmd_id, GPIO_TA_NAME); 171*15542a72SSheetal Tigadoli 172*15542a72SSheetal Tigadoli switch (cmd_id) { 173*15542a72SSheetal Tigadoli case PTA_BCM_GPIO_CMD_CFG: 174*15542a72SSheetal Tigadoli res = pta_gpio_config(param_types, params); 175*15542a72SSheetal Tigadoli break; 176*15542a72SSheetal Tigadoli case PTA_BCM_GPIO_CMD_SET: 177*15542a72SSheetal Tigadoli res = pta_gpio_set(param_types, params); 178*15542a72SSheetal Tigadoli break; 179*15542a72SSheetal Tigadoli case PTA_BCM_GPIO_CMD_GET: 180*15542a72SSheetal Tigadoli res = pta_gpio_get(param_types, params); 181*15542a72SSheetal Tigadoli break; 182*15542a72SSheetal Tigadoli default: 183*15542a72SSheetal Tigadoli EMSG("cmd: %d Not supported %s\n", cmd_id, GPIO_TA_NAME); 184*15542a72SSheetal Tigadoli res = TEE_ERROR_NOT_SUPPORTED; 185*15542a72SSheetal Tigadoli break; 186*15542a72SSheetal Tigadoli } 187*15542a72SSheetal Tigadoli 188*15542a72SSheetal Tigadoli return res; 189*15542a72SSheetal Tigadoli } 190*15542a72SSheetal Tigadoli 191*15542a72SSheetal Tigadoli pseudo_ta_register(.uuid = GPIO_SERVICE_UUID, 192*15542a72SSheetal Tigadoli .name = GPIO_TA_NAME, 193*15542a72SSheetal Tigadoli .flags = PTA_DEFAULT_FLAGS, 194*15542a72SSheetal Tigadoli .invoke_command_entry_point = invoke_command); 195