/** * zynq_gpio_set_value - Modify the state of the pin with specified value * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * @state: value used to modify the state of the specified pin * * This function calculates the register offset (i.e to lower 16 bits or * upper 16 bits) based on the given pin number and sets the state of a * gpio pin to the specified value. The state is either 0 or non-zero. */ static void zynq_gpio_set_value(struct gpio_chip *chip, unsigned int pin, int state) { unsigned int reg_offset, bank_num, bank_pin_num; struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num); if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { /* only 16 data bits in bit maskable reg */ bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); } else { reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); } /* * get the 32 bit value to be written to the mask/data register where * the upper 16 bits is the mask and lower 16 bits is the data */ if (state) state = 1; state = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & ((state << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); zynq_gpio_writereg(gpio->base_addr + reg_offset, state); }
/** * gpio_set_value - Modify the value of the pin with specified value * @gpio: gpio pin number within the device * @value: value used to modify the value of the specified pin * * This function calculates the register offset (i.e to lower 16 bits or * upper 16 bits) based on the given pin number and sets the value of a * gpio pin to the specified value. The value is either 0 or non-zero. */ int gpio_set_value(unsigned gpio, int value) { unsigned int reg_offset, bank_num, bank_pin_num; if (check_gpio(gpio) < 0) return -1; zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { /* only 16 data bits in bit maskable reg */ bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); } else { reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); } /* * get the 32 bit value to be written to the mask/data register where * the upper 16 bits is the mask and lower 16 bits is the data */ value = !!value; value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset); return 0; }
/** * zynq_gpio_set_value - Modify the state of the pin with specified value * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * @state: value used to modify the state of the specified pin * * This function calculates the register offset (i.e to lower 16 bits or * upper 16 bits) based on the given pin number and sets the state of a * gpio pin to the specified value. The state is either 0 or non-zero. */ static void zynq_gpio_set_value(struct gpio_chip *chip, unsigned int pin, int state) { unsigned long flags; unsigned int reg_offset; unsigned int bank_num, bank_pin_num; struct zynq_gpio *gpio = container_of(chip, struct zynq_gpio, chip); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num); if (bank_pin_num >= 16) { bank_pin_num -= 16; /* only 16 data bits in bit maskable reg */ reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); } else { reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); } /* * get the 32 bit value to be written to the mask/data register where * the upper 16 bits is the mask and lower 16 bits is the data */ if (state) state = 1; state = ~(1 << (bank_pin_num + 16)) & ((state << bank_pin_num) | 0xFFFF0000); spin_lock_irqsave(&gpio->gpio_lock, flags); zynq_gpio_writereg(state, gpio->base_addr + reg_offset); spin_unlock_irqrestore(&gpio->gpio_lock, flags); }