diff --git a/device.h b/device.h index e465ea5..773e115 100644 --- a/device.h +++ b/device.h @@ -103,6 +103,7 @@ extern const struct control_ops local_gpio_ops; extern const struct control_ops external_ops; extern const struct control_ops qcomlt_dbg_ops; extern const struct control_ops laurent_ops; +extern const struct control_ops pic32cx_ops; extern const struct console_ops conmux_console_ops; extern const struct console_ops console_ops; diff --git a/device_parser.c b/device_parser.c index ce8e6f3..ea05712 100644 --- a/device_parser.c +++ b/device_parser.c @@ -172,6 +172,9 @@ static void parse_board(struct device_parser *dp) } else if (!strcmp(key, "alpaca")) { dev->control_dev = strdup(value); set_control_ops(dev, &alpaca_ops); + } else if (!strcmp(key, "pic32cx")) { + dev->control_dev = strdup(value); + set_control_ops(dev, &pic32cx_ops); } else if (!strcmp(key, "external")) { dev->control_dev = strdup(value); set_control_ops(dev, &external_ops); diff --git a/drivers/pic32cx.c b/drivers/pic32cx.c new file mode 100644 index 0000000..0049fe1 --- /dev/null +++ b/drivers/pic32cx.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2026 Qualcomm Technologies, Inc. and/or its subsidiaries + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "device.h" +#include "tty.h" + +struct pic32cx { + int fd; + struct termios tios; + bool fastboot_pressed; +}; + +static void pic32cx_device_write(struct pic32cx *pic32cx, const char *fmt, ...) +{ + char buf[32]; + va_list va; + int count; + va_start(va, fmt); + count = vsnprintf(buf, sizeof(buf), fmt, va); + va_end(va); + + write(pic32cx->fd, buf, count); +} + +static void pic32cx_device_power(struct pic32cx *pic32cx, int on) +{ + pic32cx_device_write(pic32cx, "PWR_OFF %d\r", !on); +} + +static void *pic32cx_open(struct device *dev) +{ + struct pic32cx *pic32cx; + + dev->has_power_key = true; + + pic32cx = calloc(1, sizeof(*pic32cx)); + + pic32cx->fd = tty_open(dev->control_dev, &pic32cx->tios); + if (pic32cx->fd < 0) + err(1, "failed to open %s", dev->control_dev); + + pic32cx_device_power(pic32cx, 1); + + sleep(5); + + return pic32cx; +} + +static int pic32cx_power(struct device *dev, bool on) +{ + pic32cx_device_power(dev->cdb, on); + + return 0; +} + +static void pic32cx_key(struct device *dev, int key, bool asserted) +{ + struct pic32cx *pic32cx = dev->cdb; + + switch (key) { + case DEVICE_KEY_FASTBOOT: + if (asserted) + pic32cx->fastboot_pressed = true; + if (!asserted && pic32cx->fastboot_pressed) { + pic32cx_device_write(pic32cx, "MD_FASTBOOT\r"); + pic32cx->fastboot_pressed = false; + } + break; + } +} + +const struct control_ops pic32cx_ops = { + .open = pic32cx_open, + .power = pic32cx_power, + .key = pic32cx_key, +}; diff --git a/meson.build b/meson.build index c9e22ee..bc39e84 100644 --- a/meson.build +++ b/meson.build @@ -72,6 +72,7 @@ drivers_srcs = ['drivers/alpaca.c', 'drivers/ftdi-gpio.c', 'drivers/laurent.c', 'drivers/local-gpio.c', + 'drivers/pic32cx.c', 'drivers/qcomlt_dbg.c', ] diff --git a/schema.yaml b/schema.yaml index b1c6c67..41cf218 100644 --- a/schema.yaml +++ b/schema.yaml @@ -85,6 +85,10 @@ properties: description: Alpaca board control device path $ref: "#/$defs/device_path" + pic32cx: + description: PIC32CX board control device path + $ref: "#/$defs/device_path" + users: description: User access allowance for the board type: array