From 00e02a61840d0f230d25f8988d2f30100ae1388d Mon Sep 17 00:00:00 2001 From: ZhiYuanNJ <871238103@qq.com> Date: Mon, 3 Jun 2024 15:38:05 +0800 Subject: [PATCH] ch347_spi: Add spi clock frequency selection CH347 SPI interface supports up to 60M. For example, to set a 30M spi rate, use -p ch347_spi:spispeed=30M. Change-Id: If2be48929db540a6598ac0b60b37e64597156db7 Signed-off-by: ZhiYuanNJ Liu <871238103@qq.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/82776 Reviewed-by: Nicholas Chin Tested-by: build bot (Jenkins) Reviewed-by: Anastasia Klimchuk --- ch347_spi.c | 41 ++++++++++++++++++++++++++++++++++--- doc/classic_cli_manpage.rst | 10 +++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/ch347_spi.c b/ch347_spi.c index 21dcabbb8..34f2741ed 100644 --- a/ch347_spi.c +++ b/ch347_spi.c @@ -51,6 +51,11 @@ struct ch347_spi_data { int interface; }; +struct device_speeds { + const char *name; + const int divisor; +}; + /* TODO: Add support for HID mode */ static const struct dev_entry devs_ch347_spi[] = { {0x1A86, 0x55DB, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"}, /* CH347T */ @@ -63,6 +68,18 @@ static int ch347_interface[] = { CH347F_IFACE, }; +static const struct device_speeds spispeeds[] = { + {"60M", 0}, + {"30M", 1}, + {"15M", 2}, + {"7.5M", 3}, + {"3.75M", 4}, + {"1.875M", 5}, + {"937.5K", 6}, + {"468.75K", 7}, + {NULL, 0} +}; + static int ch347_spi_shutdown(void *data) { struct ch347_spi_data *ch347_data = data; @@ -266,9 +283,11 @@ static const struct spi_master spi_master_ch347_spi = { /* Largely copied from ch341a_spi.c */ static int ch347_spi_init(const struct programmer_cfg *cfg) { + char *arg; uint16_t vid = devs_ch347_spi[0].vendor_id; uint16_t pid = 0; int index = 0; + int speed_index = 2; struct ch347_spi_data *ch347_data = calloc(1, sizeof(*ch347_data)); if (!ch347_data) { msg_perr("Could not allocate space for SPI data\n"); @@ -332,9 +351,25 @@ static int ch347_spi_init(const struct programmer_cfg *cfg) (desc.bcdDevice >> 4) & 0x000F, (desc.bcdDevice >> 0) & 0x000F); - /* TODO: add programmer cfg for things like CS pin and divisor */ - if (ch347_spi_config(ch347_data, 2) < 0) + /* set CH347 clock division */ + arg = extract_programmer_param_str(cfg, "spispeed"); + if (arg) { + for (speed_index = 0; spispeeds[speed_index].name; speed_index++) { + if (!strncasecmp(spispeeds[speed_index].name, arg, strlen(spispeeds[speed_index].name))) { + break; + } + } + } + if (!spispeeds[speed_index].name || !arg) { + msg_perr("Unknown value of spispeed parameter, using default 15MHz clock spi.\n"); + speed_index = 2; + } + free(arg); + if (ch347_spi_config(ch347_data, spispeeds[speed_index].divisor) < 0) { goto error_exit; + } else { + msg_pinfo("CH347 SPI clock set to %sHz.\n", spispeeds[speed_index].name); + } return register_spi_master(&spi_master_ch347_spi, ch347_data); @@ -348,4 +383,4 @@ const struct programmer_entry programmer_ch347_spi = { .type = USB, .devs.dev = devs_ch347_spi, .init = ch347_spi_init, -}; +}; \ No newline at end of file diff --git a/doc/classic_cli_manpage.rst b/doc/classic_cli_manpage.rst index 932f4c91f..e2ce68472 100644 --- a/doc/classic_cli_manpage.rst +++ b/doc/classic_cli_manpage.rst @@ -1035,8 +1035,14 @@ as per the device. ch347_spi programmer ^^^^^^^^^^^^^^^^^^^^ -The WCH CH347 programmer does not currently support any parameters. SPI frequency is fixed at 2 MHz, and CS0 is used -as per the device. +An optional ``spispeed`` parameter could be used to specify the SPI speed. This parameter is available for the CH347T and CH347F device. +The default SPI speed is 15MHz if no value is specified. +Syntax is:: + + flashrom -p ch347_spi:spispeed=value + +where ``value`` can be ``60M``, ``30M``, ``15M``, ``7.5M``, ``3.75M``, ``1.875M``, ``937.5K``, ``468.75K``. + ni845x_spi programmer ^^^^^^^^^^^^^^^^^^^^^