/***************************************************************************
 * Copyright (C) 2026 Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * AI Disclosure: This file was largely AI-generated by Copilot (Sonnet 4.6).
 * The AI-generated portions may be considered public domain (CC0-1.0)
 * and not subject to the project's licence. The human contributor has
 * reviewed and verified that the code is correct.
 *
 * SPDX-License-Identifier: MIT and CC0-1.0
 **************************************************************************/

#ifndef GPIO_H
#define GPIO_H

#include <stdint.h>

/* apb_gpiov2 register map (pin-indexed interface)
 *
 *  Offset  Name       Access  Description
 *  0x000   SETGPIO    W       PWDATA[6:0] = pin number → drive pin high
 *  0x004   CLRGPIO    W       PWDATA[6:0] = pin number → drive pin low
 *  0x008   TOGGPIO    W       PWDATA[6:0] = pin number → toggle pin
 *  0x010   PIN0       R       bits [31:0] = sampled input state of pins 0-31
 *  0x020   OUT0       R/W     bits [31:0] = output state bitmask, pins 0-31
 *  0x030   SETSEL     W       select pin for RDSTAT
 *  0x034   RDSTAT     R       status of selected pin
 *  0x038   SETDIR     W       PWDATA[6:0]=pin, PWDATA[25:24]=dir
 *                             dir[0]=1 → push-pull output; dir[1]=1 → open-drain
 *  0x03C   SETINT     W       interrupt configuration
 *  0x040   INTACK     W       interrupt acknowledge
 */
#define GPIO_SETGPIO_OFFSET   0x000U
#define GPIO_CLRGPIO_OFFSET   0x004U
#define GPIO_TOGGPIO_OFFSET   0x008U
#define GPIO_PIN0_OFFSET      0x010U
#define GPIO_OUT0_OFFSET      0x020U
#define GPIO_SETSEL_OFFSET    0x030U
#define GPIO_RDSTAT_OFFSET    0x034U
#define GPIO_SETDIR_OFFSET    0x038U
#define GPIO_SETINT_OFFSET    0x03CU
#define GPIO_INTACK_OFFSET    0x040U

/* Direction field in SETDIR: bits [25:24] of the written word.
 * 0b01 = push-pull output enable; 0b10 = open-drain; 0b00 = input */
#define GPIO_DIR_OUTPUT (1U << 24U)

void gpio_init(void);
void gpio_set_output(uint32_t pin_mask);
void gpio_toggle(uint32_t pin_mask);
void gpio_set(uint32_t pin_mask);
void gpio_clear(uint32_t pin_mask);

/* Pad-mux control (APB SOC CTRL v1.0.0).
 * Each IO pad has a 32-bit register at SOC_CTRL_BASE + 0x400 + pad*4.
 * bits[1:0] = mux function: 0=sys, 1=perio, 2=apbio/GPIO, 3=fpgaio. */
void    gpio_setpinmux(uint8_t io_pad, uint8_t mux);
uint8_t gpio_getpinmux(uint8_t io_pad);

/* Single-pin direction and status (for CLI use).
 * dir: 0 = input, 1 = push-pull output. */
void     gpio_pin_set_dir(uint8_t pin, uint8_t dir);
uint32_t gpio_pin_read_status(uint8_t pin);

#endif /* GPIO_H */
