Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pinebook status update (20221027)
On Thu, 27 Oct 2022, Jun Ebihara wrote:
- pinebook:
Can't see audio interface.aiomixer do nothing.
http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=57030
Does the attached patch help?
Index: dev/i2c/axppmic.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/axppmic.c,v
retrieving revision 1.36
diff -u -p -r1.36 axppmic.c
--- dev/i2c/axppmic.c 7 Aug 2021 16:19:11 -0000 1.36
+++ dev/i2c/axppmic.c 29 Oct 2022 17:35:29 -0000
@@ -79,6 +79,13 @@ __KERNEL_RCSID(0, "$NetBSD: axppmic.c,v
#define AXP_ADC_RAW(_hi, _lo) \
(((u_int)(_hi) << 4) | ((_lo) & 0xf))
+#define AXP_GPIO_CTRL_REG(pin) (0x90 + (pin) * 2)
+#define AXP_GPIO_CTRL_FUNC_MASK __BITS(2,0)
+#define AXP_GPIO_CTRL_FUNC_LOW 0
+#define AXP_GPIO_CTRL_FUNC_HIGH 1
+#define AXP_GPIO_CTRL_FUNC_INPUT 2
+#define AXP_GPIO_SIGNAL_REG 0x94
+
#define AXP_FUEL_GAUGE_CTRL_REG 0xb8
#define AXP_FUEL_GAUGE_CTRL_EN __BIT(7)
@@ -327,6 +334,8 @@ struct axppmic_irq {
struct axppmic_config {
const char *name;
+ const char *gpio_compat;
+ u_int gpio_npins;
const struct axppmic_ctrl *controls;
u_int ncontrols;
u_int irq_regs;
@@ -386,6 +395,13 @@ struct axppmic_softc {
u_int sc_shut_thres;
};
+struct axppmic_gpio_pin {
+ struct axppmic_softc *pin_sc;
+ u_int pin_nr;
+ int pin_flags;
+ bool pin_actlo;
+};
+
struct axpreg_softc {
device_t sc_dev;
i2c_tag_t sc_i2c;
@@ -402,6 +418,8 @@ struct axpreg_attach_args {
static const struct axppmic_config axp803_config = {
.name = "AXP803",
+ .gpio_compat = "x-powers,axp803-gpio",
+ .gpio_npins = 2,
.controls = axp803_ctrls,
.ncontrols = __arraycount(axp803_ctrls),
.irq_regs = 6,
@@ -447,6 +465,8 @@ static const struct axppmic_config axp80
static const struct axppmic_config axp813_config = {
.name = "AXP813",
+ .gpio_compat = "x-powers,axp813-gpio",
+ .gpio_npins = 2,
.controls = axp813_ctrls,
.ncontrols = __arraycount(axp813_ctrls),
.irq_regs = 6,
@@ -583,6 +603,132 @@ static struct fdtbus_power_controller_fu
.poweroff = axppmic_power_poweroff,
};
+static int
+axppmic_gpio_ctl(struct axppmic_softc *sc, uint8_t pin, uint8_t func)
+{
+ uint8_t val;
+ int error;
+
+ KASSERT(pin < sc->sc_conf->gpio_npins);
+ KASSERT((func & ~AXP_GPIO_CTRL_FUNC_MASK) == 0);
+
+ iic_acquire_bus(sc->sc_i2c, 0);
+ error = axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_GPIO_CTRL_REG(pin),
+ &val, 0);
+ if (error == 0) {
+ val &= ~AXP_GPIO_CTRL_FUNC_MASK;
+ val |= func;
+ error = axppmic_write(sc->sc_i2c, sc->sc_addr,
+ AXP_GPIO_CTRL_REG(pin), val, 0);
+ }
+ iic_release_bus(sc->sc_i2c, 0);
+
+ return error;
+}
+
+static void *
+axppmic_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
+{
+ struct axppmic_softc *sc = device_private(dev);
+ struct axppmic_gpio_pin *gpin;
+ const u_int *gpio = data;
+ int error;
+
+ if (len != 12) {
+ return NULL;
+ }
+
+ const uint8_t pin = be32toh(gpio[1]) & 0xff;
+ const bool actlo = be32toh(gpio[2]) & 1;
+
+ if (pin >= sc->sc_conf->gpio_npins) {
+ return NULL;
+ }
+
+ if ((flags & GPIO_PIN_INPUT) != 0) {
+ error = axppmic_gpio_ctl(sc, pin, AXP_GPIO_CTRL_FUNC_INPUT);
+ if (error != 0) {
+ return NULL;
+ }
+ }
+
+ gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
+ gpin->pin_sc = sc;
+ gpin->pin_nr = pin;
+ gpin->pin_flags = flags;
+ gpin->pin_actlo = actlo;
+
+ return gpin;
+}
+
+static void
+axppmic_gpio_release(device_t dev, void *priv)
+{
+ struct axppmic_softc *sc = device_private(dev);
+ struct axppmic_gpio_pin *gpin = priv;
+
+ axppmic_gpio_ctl(sc, gpin->pin_nr, AXP_GPIO_CTRL_FUNC_INPUT);
+
+ kmem_free(gpin, sizeof(*gpin));
+}
+
+static int
+axppmic_gpio_read(device_t dev, void *priv, bool raw)
+{
+ struct axppmic_softc *sc = device_private(dev);
+ struct axppmic_gpio_pin *gpin = priv;
+ uint8_t data;
+ int error, val;
+
+ KASSERT(sc == gpin->pin_sc);
+
+ const uint8_t data_mask = __BIT(gpin->pin_nr);
+
+ iic_acquire_bus(sc->sc_i2c, 0);
+ error = axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_GPIO_SIGNAL_REG,
+ &data, 0);
+ iic_release_bus(sc->sc_i2c, 0);
+
+ if (error != 0) {
+ device_printf(dev, "WARNING: failed to read pin %d: %d\n",
+ gpin->pin_nr, error);
+ val = 0;
+ } else {
+ val = __SHIFTOUT(data, data_mask);
+ }
+ if (!raw && gpin->pin_actlo) {
+ val = !val;
+ }
+
+ return val;
+}
+
+static void
+axppmic_gpio_write(device_t dev, void *priv, int val, bool raw)
+{
+ struct axppmic_softc *sc = device_private(dev);
+ struct axppmic_gpio_pin *gpin = priv;
+ int error;
+
+ if (!raw && gpin->pin_actlo) {
+ val = !val;
+ }
+
+ error = axppmic_gpio_ctl(sc, gpin->pin_nr,
+ val == 0 ? AXP_GPIO_CTRL_FUNC_LOW : AXP_GPIO_CTRL_FUNC_HIGH);
+ if (error != 0) {
+ device_printf(dev, "WARNING: failed to write pin %d: %d\n",
+ gpin->pin_nr, error);
+ }
+}
+
+static struct fdtbus_gpio_controller_func axppmic_gpio_funcs = {
+ .acquire = axppmic_gpio_acquire,
+ .release = axppmic_gpio_release,
+ .read = axppmic_gpio_read,
+ .write = axppmic_gpio_write,
+};
+
static void
axppmic_task_shut(void *priv)
{
@@ -1041,6 +1187,14 @@ axppmic_attach(device_t parent, device_t
fdtbus_register_power_controller(sc->sc_dev, sc->sc_phandle,
&axppmic_power_funcs);
+ if (c->gpio_compat != NULL) {
+ phandle = of_find_bycompat(sc->sc_phandle, c->gpio_compat);
+ if (phandle > 0) {
+ fdtbus_register_gpio_controller(self, phandle,
+ &axppmic_gpio_funcs);
+ }
+ }
+
phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
if (phandle > 0) {
aaa.reg_i2c = sc->sc_i2c;
Home |
Main Index |
Thread Index |
Old Index