diff --git a/board/m5stack/module-LLM/linux-enable-m5stack.config b/board/m5stack/module-LLM/linux-enable-m5stack.config index 34cf512..57d711c 100644 --- a/board/m5stack/module-LLM/linux-enable-m5stack.config +++ b/board/m5stack/module-LLM/linux-enable-m5stack.config @@ -1 +1,28 @@ -CONFIG_AXERA_OSAL \ No newline at end of file +CONFIG_SWAP=y +CONFIG_TYPEC_SGM7220=y +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" + +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_F_OBEX=m +CONFIG_USB_G_SERIAL=m +CONFIG_TYPEC_SGM7220=y + + +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_ARC4=m + + diff --git a/board/m5stack/module-LLM/patches/linux/0011-linux-4.19.125-sgm7220.patch b/board/m5stack/module-LLM/patches/linux/0011-linux-4.19.125-sgm7220.patch new file mode 100644 index 0000000..aac1ca3 --- /dev/null +++ b/board/m5stack/module-LLM/patches/linux/0011-linux-4.19.125-sgm7220.patch @@ -0,0 +1,526 @@ +--- a/drivers/usb/typec/axera_sgm7220.c 2024-12-04 21:26:21.229571851 +0800 ++++ b/drivers/usb/typec/axera_sgm7220.c 2024-12-04 21:26:16.421480862 +0800 +@@ -0,0 +1,497 @@ ++/************************************************************************************************** ++ * ++ * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. ++ * ++ * This source file is the property of Axera Semiconductor Co., Ltd. and ++ * may not be copied or distributed in any isomorphic form without the prior ++ * written consent of Axera Semiconductor Co., Ltd. ++ * ++ **************************************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++// #include ++#include ++// #include "tcpm/tcpci.h" ++#include "../dwc3/dwc3-axera.h" ++ ++ ++#undef dev_dbg ++#define dev_dbg(dev, fmt, ...) \ ++ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) ++ ++ ++//reg 0x0a ++#define I2C_SOFT_RESET 3 ++#define SOURCE_PREF 1 ++ ++//reg 0x09 ++#define INTERRUPT_STATUS 4 ++ ++//attach state ++#define ATTACH_STATE 6 ++#define NOT_ATTACH 0 ++#define DFP 1 ++#define UFP 2 ++#define ACCESSORY 3 ++ ++//cable dir ++#define CABLE_DIR 5 ++#define CC1 0 ++#define CC2 1 //default ++ ++ ++#define DWC3_GCTL_PRTCAP_HOST 1 ++#define DWC3_GCTL_PRTCAP_DEVICE 2 ++#define DWC3_GCTL_PRTCAP_OTG 3 ++ ++ ++#define SGM7220_DEVICE_ID_LEN 8 ++static char sgm7220_device_id[SGM7220_DEVICE_ID_LEN] = {0x30, 0x32, 0x33, 0x42, 0x53, 0x55, 0x54, 0x00}; ++ ++ ++struct sgm7220_chip { ++ // struct tcpci_data data; ++ struct device *dev; ++ struct i2c_client *client; ++ int gpio; //interrupt gpio ++ // int chanel_sel_gpio; //chanel switch gpio for DIO3340 ++ const char *realted_usb_name; //which usb to bind ++}; ++ ++ ++// static const struct regmap_config sgm7220_regmap_config = { ++// .reg_bits = 8, ++// .val_bits = 8, ++// .max_register = 0xFF, /* 0x80 .. 0xFF are vendor defined */ ++// }; ++ ++ ++static int sgm7220_read8(struct sgm7220_chip *chip, unsigned int reg, u8 *val) ++{ ++ // return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8)); ++ int ret; ++ ret = i2c_smbus_read_byte_data(chip->client, reg); ++ if (ret < 0) { ++ dev_err(chip->dev, "Failed to read byte from I2C device\n"); ++ return ret; ++ } ++ *val = (u8)ret; ++ return 0; ++} ++ ++static int sgm7220_write8(struct sgm7220_chip *chip, unsigned int reg, u8 val) ++{ ++ // return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8)); ++ int ret; ++ ret = i2c_smbus_write_byte_data(chip->client, reg, val); ++ if (ret < 0) { ++ dev_err(chip->dev, "Failed to write byte data to I2C device\n"); ++ return ret; ++ } ++ return 0; ++} ++ ++ ++static int sgm7220_init(struct sgm7220_chip *chip) ++{ ++ int ret; ++ char val; ++ ++ ret = sgm7220_read8(chip, 0x0A, &val); ++ if (ret < 0) ++ return ret; ++ ++ //DRP will perform Try.SNK ++ val |= (1 << SOURCE_PREF); //bit[2.1] = 01 ++ ret = sgm7220_write8(chip, 0x0A, val); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++ ++static int clear_sgm7220_irq(struct sgm7220_chip *chip) ++{ ++ int ret; ++ char val; ++ ++ ret = sgm7220_read8(chip, 0x09, &val); ++ if (ret < 0) ++ return ret; ++ ++ //write 1 to clear ++ ret = sgm7220_write8(chip, 0x09, val); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++ ++static int set_usb_mode(struct sgm7220_chip *chip, char mode) ++{ ++ struct list_head *head; ++ struct dwc3_dev_list *node; ++ ++ head = get_dwc3_list(); ++ ++ list_for_each_entry(node, head, list_node) { ++ if (!strncmp(node->dwc->dev->kobj.name, chip->realted_usb_name, strlen(chip->realted_usb_name))) { ++ dev_dbg(chip->dev, "dwc3 usb name: %s\n", node->dwc->dev->kobj.name); ++ dwc3_set_mode(node->dwc, mode); ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++ ++//type-c forward and reverse plugin function ++// static void select_usb3_channel(struct sgm7220_chip *chip, char cc) ++// { ++ // gpio_set_value(chip->chanel_sel_gpio, cc); ++// } ++ ++ ++static int handle_not_attach_mode(struct sgm7220_chip *chip) ++{ ++ dev_info(chip->dev, "typec disconnect, handle_not_attach_mode as device mode\n"); ++ set_usb_mode(chip, DWC3_GCTL_PRTCAP_DEVICE); ++ ++ return 0; ++} ++ ++static int handle_dfp_mode(struct sgm7220_chip *chip, char cable_dir) ++{ ++ dev_info(chip->dev, "typec connected, handle_dfp_mode host, cable direction:%d\n", cable_dir); ++ // select_usb3_channel(chip, cable_dir); ++ set_usb_mode(chip, DWC3_GCTL_PRTCAP_HOST); ++ ++ return 0; ++} ++ ++static int handle_ufp_mode(struct sgm7220_chip *chip, char cable_dir) ++{ ++ dev_info(chip->dev, "typec connected, handle_ufp_mode device, cable direction:%d\n", cable_dir); ++ // select_usb3_channel(chip, cable_dir); ++ set_usb_mode(chip, DWC3_GCTL_PRTCAP_DEVICE); ++ ++ return 0; ++} ++ ++ ++static irqreturn_t sgm7220_irq(int irq, void *dev_id) ++{ ++ int ret; ++ struct sgm7220_chip *chip = dev_id; ++ unsigned char val_0x09; ++ unsigned char val_0x08; ++ unsigned char attach_mode; ++ unsigned char cable_dir; ++ ++ ++ ret = clear_sgm7220_irq(chip); ++ if (ret < 0) ++ dev_err(chip->dev, "clear_sgm7220_irq fail\n"); ++ ++ ret = sgm7220_read8(chip, 0x09, &val_0x09); ++ if (ret < 0) ++ dev_err(chip->dev, "read reg 0x09 fail\n"); ++ ++ ret = sgm7220_read8(chip, 0x08, &val_0x08); ++ if (ret < 0) ++ dev_err(chip->dev, "read reg 0x08 fail\n"); ++ ++ dev_dbg(chip->dev, "sgm7220 generate a irq, reg addr 0x09:%x, addr 0x08:%x\n", ++ val_0x09, val_0x08); ++ ++ cable_dir = (val_0x09 >> CABLE_DIR) & 0x1; ++ attach_mode = (val_0x09 >> ATTACH_STATE) & 0x3; ++ switch (attach_mode) { ++ case NOT_ATTACH: ++ handle_not_attach_mode(chip); ++ break; ++ case DFP:// (作为)主机模式,读取usb设备 ++ handle_dfp_mode(chip, cable_dir); ++ break; ++ case UFP:// (作为)设备模式, ++ handle_ufp_mode(chip, cable_dir); ++ break; ++ case ACCESSORY: ++ dev_info(chip->dev, "attach state: accessory\n"); ++ break; ++ default: ++ dev_err(chip->dev, "a bad attach state\n"); ++ break; ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++ ++static int sgm7220_init_irq(struct sgm7220_chip *chip, ++ struct i2c_client *client) ++{ ++ int ret; ++ ++ ret = devm_request_threaded_irq(chip->dev, client->irq, NULL, ++ sgm7220_irq, ++ IRQF_ONESHOT | IRQF_TRIGGER_LOW, ++ dev_name(chip->dev), chip); ++ if (ret < 0) ++ return ret; ++ ++ enable_irq_wake(client->irq); ++ ++ return 0; ++} ++ ++#if 0 ++static int sgm7220_sw_reset(struct sgm7220_chip *chip) ++{ ++ int ret; ++ char val; ++ ++ ret = sgm7220_read8(chip, 0x0A, &val); ++ if (ret < 0) ++ return ret; ++ ++ val |= (1 << I2C_SOFT_RESET); ++ ret = sgm7220_write8(chip, 0x0A, val); ++ if (ret < 0) ++ return ret; ++ ++ //max is 14ms, so set 20ms ++ mdelay(20); ++ return 0; ++} ++#endif ++ ++static int sgm7220_sw_reset(struct sgm7220_chip *chip) ++{ ++ int ret; ++ char val; ++ int cnt = 20; ++ ++ ret = sgm7220_read8(chip, 0x0A, &val); ++ if (ret < 0) ++ return ret; ++ ++ val |= (1 << I2C_SOFT_RESET); ++ ret = sgm7220_write8(chip, 0x0A, val); ++ if (ret < 0) ++ return ret; ++ ++ while (cnt > 0) { ++ mdelay(15); //max is 14ms, so set 15ms ++ ret = sgm7220_read8(chip, 0x0A, &val); ++ if (ret < 0) ++ return ret; ++ ++ if ((val & (1 << I2C_SOFT_RESET)) == 0) //clear success ++ return 0; ++ ++ cnt--; ++ } ++ ++ dev_err(chip->dev, "sgm7220 soft reset timeout\n"); ++ return -1; ++} ++ ++ ++static int sgm7220_check_revision(struct i2c_client *i2c) ++{ ++ int i; ++ char device_id; ++ ++ for (i = 0; i < SGM7220_DEVICE_ID_LEN; i++) { ++ device_id = i2c_smbus_read_byte_data(i2c, i); //device id reg addr is 0x00-0x07 ++ if (device_id < 0) ++ return device_id; ++ ++ if (device_id != sgm7220_device_id[i]) { ++ dev_err(&i2c->dev, "device id is not correct\n"); ++ return -ENODEV; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int init_int_gpio(struct sgm7220_chip *chip, struct i2c_client *client) ++{ ++ struct device_node *node; ++ int ret = 0; ++ ++ node = chip->dev->of_node; ++ chip->gpio = of_get_named_gpio(node, "int-gpio", 0); ++ if (!gpio_is_valid(chip->gpio)) { ++ ret = chip->gpio; ++ dev_err(chip->dev, "cannot get dts gpio node: int-gpio, ret=%d", ret); ++ return ret; ++ } ++ ++ ret = devm_gpio_request(chip->dev, chip->gpio, "int-gpio"); ++ if (ret < 0) { ++ dev_err(chip->dev, "cannot request GPIO: %d, ret=%d", chip->gpio, ret); ++ return ret; ++ } ++ ++ ret = gpio_direction_input(chip->gpio); ++ if (ret < 0) { ++ dev_err(chip->dev, "cannot set GPIO to input mode, ret=%d", ret); ++ return ret; ++ } ++ ++ ret = gpio_to_irq(chip->gpio); ++ if (ret < 0) { ++ dev_err(chip->dev, "cannot request IRQ for GPIO, ret=%d", ret); ++ return ret; ++ } ++ client->irq = ret; ++ ++ return 0; ++} ++ ++ ++// static int init_chanel_switch_gpio(struct sgm7220_chip *chip) ++// { ++ // struct device_node *node; ++ // int ret = 0; ++ ++ // node = chip->dev->of_node; ++ // chip->chanel_sel_gpio = of_get_named_gpio(node, "chanel-sel", 0); ++ // if (!gpio_is_valid(chip->chanel_sel_gpio)) { ++ // ret = chip->chanel_sel_gpio; ++ // dev_err(chip->dev, "cannot get dts gpio node: chanel-sel, ret=%d", ret); ++ // return ret; ++ // } ++ ++ // ret = devm_gpio_request(chip->dev, chip->chanel_sel_gpio, "chanel-sel"); ++ // if (ret < 0) { ++ // dev_err(chip->dev, "cannot request GPIO: %d, ret=%d", chip->chanel_sel_gpio, ret); ++ // return ret; ++ // } ++ ++ // ret = gpio_direction_output(chip->chanel_sel_gpio, CC2); ++ // if (ret < 0) { ++ // dev_err(chip->dev, "cannot set GPIO to output mode, ret=%d", ret); ++ // return ret; ++ // } ++ ++// return 0; ++// } ++ ++ ++static int sgm7220_probe(struct i2c_client *client, ++ const struct i2c_device_id *i2c_id) ++{ ++ int ret = 0; ++ struct sgm7220_chip *chip; ++ dev_dbg(&client->dev, "sgm7220_probe\n"); ++ ++ ret = sgm7220_check_revision(client); ++ if (ret < 0) { ++ dev_err(&client->dev, "check device id fail\n"); ++ return ret; ++ } ++ ++ chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); ++ if (!chip) ++ return -ENOMEM; ++ ++ // chip->data.regmap = devm_regmap_init_i2c(client, ++ // &sgm7220_regmap_config); ++ // if (IS_ERR(chip->data.regmap)) ++ // return PTR_ERR(chip->data.regmap); ++ ++ chip->client = client; ++ chip->dev = &client->dev; ++ i2c_set_clientdata(client, chip); ++ ++ ret = sgm7220_sw_reset(chip); ++ if (ret < 0) { ++ dev_err(&client->dev, "sgm7220 soft reset fail\n"); ++ return ret; ++ } ++ ++ if (!client->irq) { ++ ret = init_int_gpio(chip, client); ++ if (ret < 0) { ++ dev_err(&client->dev, "init interrupt gpio fail\n"); ++ return ret; ++ } ++ } ++ ++ ret = sgm7220_init_irq(chip, client); ++ if (ret < 0) { ++ dev_err(&client->dev, "sgm7220 init irq fail\n"); ++ return ret; ++ } ++ ++ // ret = init_chanel_switch_gpio(chip); ++ // if (ret < 0) { ++ // dev_err(&client->dev, "init usb channel switch gpio fail\n"); ++ // return ret; ++ // } ++ ++ ret = of_property_read_string(chip->dev->of_node, "bind-usb", &chip->realted_usb_name); ++ if (ret < 0) { ++ dev_err(chip->dev, "cannot get bind-usb property from dts node, ret=%d", ret); ++ return ret; ++ } ++ dev_info(chip->dev, "typeC realted usb device name: %s\n", chip->realted_usb_name); ++ ++ sgm7220_init(chip); ++ ++ return 0; ++} ++ ++ ++static int sgm7220_remove(struct i2c_client *client) ++{ ++ struct sgm7220_chip *chip = i2c_get_clientdata(client); ++ ++ dev_info(chip->dev, "remove sgm7220 typeC driver\n"); ++ return 0; ++} ++ ++ ++static const struct i2c_device_id sgm7220_id[] = { ++ { "sgm7220", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, sgm7220_id); ++ ++#ifdef CONFIG_OF ++static const struct of_device_id sgm7220_of_match[] = { ++ { .compatible = "axera,sgm7220", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, sgm7220_of_match); ++#endif ++ ++ ++static struct i2c_driver sgm7220_i2c_driver = { ++ .driver = { ++ .name = "sgm7220", ++ .of_match_table = of_match_ptr(sgm7220_of_match), ++ }, ++ .probe = sgm7220_probe, ++ .remove = sgm7220_remove, ++ .id_table = sgm7220_id, ++}; ++module_i2c_driver(sgm7220_i2c_driver); ++ ++ ++MODULE_AUTHOR("baoli wang "); ++MODULE_DESCRIPTION("SGM7220 USB Type-C Controller Driver"); ++MODULE_LICENSE("GPL"); +--- a/drivers/usb/typec/Kconfig 2024-12-04 21:26:35.653844782 +0800 ++++ b/drivers/usb/typec/Kconfig 2024-12-04 21:26:32.005775760 +0800 +@@ -72,6 +72,15 @@ + Type-C Port Controller Manager to provide USB PD and USB + Type-C functionalities. + ++config TYPEC_SGM7220 ++ tristate "AXERA SGM7220 Type-C chip driver" ++ depends on I2C ++ select REGMAP_I2C ++ help ++ AXERA SGM7220 Type-C chip driver that works with ++ Type-C Port Controller Manager to provide USB PD and USB ++ Type-C functionalities. ++ + source "drivers/usb/typec/fusb302/Kconfig" + + config TYPEC_WCOVE +--- a/drivers/usb/typec/Makefile 2024-12-04 21:26:29.049719829 +0800 ++++ b/drivers/usb/typec/Makefile 2024-12-04 21:26:24.397631800 +0800 +@@ -10,3 +10,4 @@ + obj-$(CONFIG_TYPEC) += mux/ + obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o + obj-$(CONFIG_TYPEC_RT1711H) += tcpci_rt1711h.o ++obj-$(CONFIG_TYPEC_SGM7220) += axera_sgm7220.o +\ 文件尾没有换行符