Compare commits

1 Commits

Author SHA1 Message Date
a24c65a6ea msm5.15: Import ayn changes from ayn_8550.xz (01/18/2026)
Signed-off-by: AnierinB <anierin@evolution-x.org>
2026-01-19 09:53:56 +00:00
35 changed files with 1952 additions and 42 deletions

View File

@@ -32,7 +32,7 @@ CONFIG_CORESIGHT_TGU=m
CONFIG_CORESIGHT_TPDA=m
CONFIG_CORESIGHT_TPDM=m
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
CONFIG_DRM_LT9611UXC=m
# CONFIG_DRM_LT9611UXC is not set
CONFIG_EDAC_QCOM=m
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
@@ -135,10 +135,16 @@ CONFIG_NL80211_TESTMODE=y
CONFIG_NOP_USB_XCEIV=m
CONFIG_NVMEM_SPMI_SDAM=m
CONFIG_NVME_CORE=m
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_QUALCOMM=y
# CONFIG_NVME_HWMON is not set
# CONFIG_NVME_MULTIPATH is not set
# CONFIG_NXP_TJA11XX_PHY is not set
CONFIG_PCI_MSM=m
CONFIG_PAGE_POOL=y
CONFIG_PHYLINK=y
#CONFIG_QPS615=y
#CONFIG_r8168=y
CONFIG_PDR_INDICATION_NOTIF_TIMEOUT=9000
CONFIG_PHY_QCOM_UFS=m
CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m
@@ -561,3 +567,4 @@ CONFIG_VIRT_DRIVERS=y
# CONFIG_WFX is not set
# CONFIG_WILC1000_SDIO is not set
# CONFIG_WILC1000_SPI is not set
CONFIG_PWM_PM=m

View File

@@ -35,7 +35,7 @@ CONFIG_CORESIGHT_TGU=m
CONFIG_CORESIGHT_TPDA=m
CONFIG_CORESIGHT_TPDM=m
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
# CONFIG_DRM_LT9611UXC is not set
CONFIG_DRM_LT9611UXC=m
CONFIG_EDAC_QCOM=m
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y

View File

@@ -68,6 +68,7 @@ CONFIG_DRM_TTM=y
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EZX_PCAP is not set
CONFIG_FB=y
CONFIG_FB_CMDLINE=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GH_ARM64_DRV=y

View File

@@ -6,8 +6,8 @@
################################################################################
## Variant setup
MSM_ARCH=kalama
VARIANTS=(consolidate gki)
[ -z "${VARIANT}" ] && VARIANT=consolidate
VARIANTS=gki
[ -z "${VARIANT}" ] && VARIANT=gki
ABL_SRC=bootable/bootloader/edk2
BOOT_IMAGE_HEADER_VERSION=4

View File

@@ -184,6 +184,11 @@ static const struct __extcon_info {
.id = EXTCON_MECHANICAL,
.name = "MECHANICAL",
},
[EXTCON_DEMO_A] = {
.type = EXTCON_TYPE_MISC,
.id = EXTCON_DEMO_A,
.name = "EXTCON_DEMO_AENG",
},
{ /* sentinel */ }
};

View File

@@ -50,6 +50,7 @@ config I2C_COMPAT
config I2C_CHARDEV
tristate "I2C device interface"
default y
help
Say Y here to use i2c-* device files, usually found in the /dev
directory on your system. They make it possible to have user-space

View File

@@ -2425,6 +2425,7 @@ static int geni_i2c_suspend_late(struct device *device)
pm_runtime_set_suspended(device);
pm_runtime_enable(device);
}
pm_runtime_enable(device);
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret);
return 0;

View File

@@ -1380,6 +1380,12 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9,
SCALE_HW_CALIB_PM7_SMB_TEMP)
[ADC5_GEN3_AMUX2_THM] = ADC5_CHAN_VOLT("amux2_volt", 1,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX4_THM] = ADC5_CHAN_VOLT("amux4_volt", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX5_THM] = ADC5_CHAN_VOLT("amux5_volt", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0,
SCALE_HW_CALIB_PM7_CHG_TEMP)
[ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8,

View File

@@ -1666,6 +1666,7 @@ static int haptics_wait_brake_complete(struct haptics_chip *chip)
t_lra_us = (chip->config.cl_t_lra_us) ?
chip->config.cl_t_lra_us : chip->config.t_lra_us;
t_lra_us = 2000;
brake_length_us = get_brake_play_length_us(play->brake, t_lra_us);
@@ -1673,7 +1674,7 @@ static int haptics_wait_brake_complete(struct haptics_chip *chip)
brake_length_us += t_lra_us;
delay_us = t_lra_us / 2;
timeout = brake_length_us / delay_us + 1;
dev_dbg(chip->dev, "wait %d us for brake pattern to complete\n", brake_length_us);
dev_warn(chip->dev, "wait %d us for brake pattern to complete timeout=%d delay_us=%d\n", brake_length_us, timeout, delay_us);
/* poll HPWR_DISABLED to guarantee the brake pattern has been played completely */
do {
@@ -4065,6 +4066,8 @@ static int haptics_create_debugfs(struct haptics_chip *chip)
debugfs_create_u32("fifo_empty_thresh", 0600, hap_dir,
&chip->config.fifo_empty_thresh);
debugfs_create_u32("user_vmax_mv", 0666, hap_dir,
&chip->config.vmax_mv);
chip->debugfs_dir = hap_dir;
return 0;
@@ -4341,7 +4344,7 @@ static int haptics_parse_per_effect_dt(struct haptics_chip *chip,
return rc;
}
if (!config->is_erm)
//if (!config->is_erm)
effect->auto_res_disable = of_property_read_bool(node,
"qcom,wf-auto-res-disable");
@@ -5591,8 +5594,9 @@ static int haptics_probe(struct platform_device *pdev)
rc = haptics_hw_init(chip);
if (rc < 0) {
dev_err(chip->dev, "Initialize HW failed, rc = %d\n", rc);
return rc;
dev_err(chip->dev, "probe() Initialize HW failed, rc = %d\n", rc);
if(rc != -EBUSY)
return rc;
}
if (is_swr_supported(chip)) {
@@ -5600,7 +5604,8 @@ static int haptics_probe(struct platform_device *pdev)
if (rc < 0) {
dev_err(chip->dev, "Initialize swr slave regulator failed, rc = %d\n",
rc);
return rc;
if(rc != -EBUSY)
return rc;
}
}
@@ -5610,7 +5615,8 @@ static int haptics_probe(struct platform_device *pdev)
if (rc < 0) {
dev_err(chip->dev, "request fifo-empty IRQ failed, rc=%d\n",
rc);
return rc;
if(rc != -EBUSY)
return rc;
}
mutex_init(&chip->play.lock);
@@ -5714,7 +5720,7 @@ static int haptics_ds_resume_config(struct device *dev)
rc = haptics_hw_init(chip);
if (rc < 0) {
dev_err(chip->dev, "Initialize HW failed, rc = %d\n", rc);
dev_err(chip->dev, "resume() Initialize HW failed, rc = %d\n", rc);
return rc;
}

View File

@@ -285,6 +285,9 @@ config LEDS_QTI_FLASH
To compile this driver as a module, choose M here: the
module will be called leds-qti-flash.
config PWM_PM
tristate "Support for PWM_PM"
config LEDS_QPNP_FLASH_V2
tristate "Support for QPNP V2 Flash LEDs"
depends on LEDS_CLASS && MFD_SPMI_PMIC

View File

@@ -110,3 +110,4 @@ obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
# LED Blink
obj-y += blink/
obj-$(CONFIG_PWM_PM) += gpio5_pwm.o

550
drivers/leds/gpio5_pwm.c Normal file
View File

@@ -0,0 +1,550 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include <mydebug.h>
#define SAMPLING_TIME 100
#define DP_HDMI_UNUSE 2
static int thermal_mode = 0;
int en_backlight = 1;
static int dp_state = 0;
static int hdmi_state = 0;
EXPORT_SYMBOL(en_backlight);
int secondary_en_backlight = 1;
EXPORT_SYMBOL(secondary_en_backlight);
//extern int dp_display_connected;
//extern int default_display_connected;
int dp_display_connected = 0; //redefined
int default_display_connected = 0;
struct gpio5_pwm_data
{
unsigned int state;
unsigned int duty_ns;
unsigned int period_ns;
unsigned int fan_en_gpio;
unsigned int fan_int_gpio;
int fan_irq;
struct pwm_device *pwm_dev;
};
struct class gpio5_pwm_class;
static struct gpio5_pwm_data *data;
static int fan_fg_count,rpm;
//static struct timeval fg_time;
//static unsigned long fg_time_sec_start;
//static unsigned long fg_time_sec_end;
//static unsigned long fg_time_usec_start;
//static unsigned long fg_time_usec_end;
//static unsigned long fg_time_sec;
//static unsigned long fg_time_usec;
static ssize_t state_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->state));
}
static ssize_t state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
if (sysfs_streq(buf, "1"))
{
gpio_direction_output(data->fan_en_gpio, 1);
__gpio_set_value(data->fan_en_gpio,1);
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
printk("[kevin]%s: %d %d\n", __func__, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
data->state = 1;
//pr_err("kevin fan_en_gpio = 1!\n");
}
else if (sysfs_streq(buf, "0"))
{
pwm_disable(data->pwm_dev);
data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
//pr_err("kevin fan_en_gpio = 0!\n");
}
return len;
}
static CLASS_ATTR_RW(state);
static ssize_t duty_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->duty_ns));
}
static ssize_t duty_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &data->duty_ns);
if (rc < 0)
pr_err("get duty value failed!\n");
//if(data->duty_ns <= data->period_ns){
// data->duty_ns = data->period_ns-data->duty_ns;
//}
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
return len;
}
static CLASS_ATTR_RW(duty);
static ssize_t thermal_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", thermal_mode));
}
static ssize_t thermal_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &thermal_mode);
if (rc < 0)
pr_err("get thermal_mode value failed!\n");
return len;
}
static CLASS_ATTR_RW(thermal);
static ssize_t en_backlight_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", en_backlight));
}
static ssize_t en_backlight_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &en_backlight);
if (rc < 0)
pr_err("get en_backlight value failed!\n");
return len;
}
static CLASS_ATTR_RW(en_backlight);
static ssize_t secondary_en_backlight_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", secondary_en_backlight));
}
static ssize_t secondary_en_backlight_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &secondary_en_backlight);
if (rc < 0)
pr_err("get secondary_en_backlight value failed!\n");
return len;
}
static CLASS_ATTR_RW(secondary_en_backlight);
static ssize_t dp_state_show(struct class *class, struct class_attribute *attr, char *buf)
{
if(dp_display_connected == DP_HDMI_UNUSE)
dp_state = 0;
else
dp_state = dp_display_connected;
return (sprintf(buf, "%u\n", dp_state));
}
static ssize_t dp_state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
int pre_dp_state = dp_state;
rc = kstrtouint(buf, 0, &dp_state);
if (rc < 0)
pr_err("get dp_state value failed!\n");
if(dp_state != 0 && dp_state != 1){
dp_state = pre_dp_state;
}
dp_display_connected = dp_state;
return len;
}
static CLASS_ATTR_RW(dp_state);
static ssize_t hdmi_state_show(struct class *class, struct class_attribute *attr, char *buf)
{
if(default_display_connected == DP_HDMI_UNUSE)
hdmi_state = 0;
else
hdmi_state = default_display_connected;
return (sprintf(buf, "%u\n", hdmi_state));
}
static ssize_t hdmi_state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
int pre_hdmi_state = hdmi_state;
rc = kstrtouint(buf, 0, &hdmi_state);
if (rc < 0)
pr_err("get hdmi_state value failed!\n");
if(hdmi_state != 0 && hdmi_state != 1){
hdmi_state = pre_hdmi_state;
}
default_display_connected = hdmi_state;
return len;
}
static CLASS_ATTR_RW(hdmi_state);
static ssize_t period_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->period_ns));
}
static ssize_t period_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &data->period_ns);
if (rc < 0)
pr_err("get period value failed!\n");
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
return len;
}
static CLASS_ATTR_RW(period);
//cat sys/class/gpio5_pwm2/speed
static ssize_t speed_show(struct class *class, struct class_attribute *attr, char *buf)
{
rpm = 0;
fan_fg_count = 0;
enable_irq(data->fan_irq);
mdelay(SAMPLING_TIME);
disable_irq(data->fan_irq);
//printk("fan_fg_count = %d\n",fan_fg_count);
rpm = 60000/(SAMPLING_TIME*2)*fan_fg_count;
return (sprintf(buf, "%d\n", rpm));
}
static CLASS_ATTR_RO(speed);
static irqreturn_t fan_irq_handler(int irq, void *data)
{
fan_fg_count = fan_fg_count+1;
return IRQ_HANDLED;
}
#if 0
static irqreturn_t fan_irq_handler(int irq, void *data)
{
//printk("******* %s ********start \n",__func__);
if (fan_fg_count == 0){
do_gettimeofday(&fg_time);
fg_time_sec_start = fg_time.tv_sec;
fg_time_usec_start = fg_time.tv_usec;
//printk("******* fg start time sec:%ld, usec: %ld\n", fg_time.tv_sec, fg_time.tv_usec);
//disable_irq_nosync(fan_irq);
}
fan_fg_count++;
if (fan_fg_count == 3){
do_gettimeofday(&fg_time);
fg_time_sec_end = fg_time.tv_sec;
fg_time_usec_end = fg_time.tv_usec;
//printk("********** fg end time sec:%ld, usec: %ld\n", fg_time.tv_sec, fg_time.tv_usec);
fg_time_sec = fg_time_sec_end - fg_time_sec_start;
if(fg_time_usec_end > fg_time_usec_start)
fg_time_usec = fg_time_usec_end - fg_time_usec_start;
else{
fg_time_usec = 1000000+fg_time_usec_end - fg_time_usec_start;
fg_time_sec = fg_time_sec - 1;
}
rpm = 1000/((fg_time_sec *1000 + fg_time_usec/1000));//unit: 1sec/rpm
//printk("********** rpm = %d \n",rpm);
printk("count=%d,s_sec:%ld, s_usec: %ld,e_sec:%ld,e_usec:%ld\n",fan_fg_count, fg_time_sec_start, fg_time_usec_start,fg_time_sec_end,fg_time_usec_end);
}
//printk("******* %s ********end \n",__func__);
return IRQ_HANDLED;
}
#endif
/*
static int fan_pwm_suspend(struct device *dev)
{
if (data->state) {
pwm_disable(data->pwm_dev);
// data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
pr_err("kevin fan_en_gpio = 0!\n");
}
return 0;
}
static int fan_pwm_resume(struct device *dev)
{
if (data->state) {
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
printk("[kevin]%s: %d %d\n", __func__, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
// data->state = 1;
gpio_direction_output(data->fan_en_gpio, 1);
__gpio_set_value(data->fan_en_gpio,1);
//pr_err("kevin fan_en_gpio = 1!\n");
}
return 0;
}
*/
static int gpio5_pwm_probe(struct platform_device *pdev)
{
int rc = 0;
int ret = 0;
struct device_node *of_node = pdev->dev.of_node;
printk("xxh ------------- %s start!\n",__func__);
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
{
return -ENOMEM;
}
data->pwm_dev = devm_of_pwm_get(&pdev->dev, of_node, NULL);
if (!data->pwm_dev)
{
pr_err("%s: failed to request pwm\n", __func__);
rc = -EINVAL;
goto error;
}
rc = of_property_read_s32(of_node, "gpio5-pwm-duty-ns", &data->duty_ns);
if (rc)
{
pr_warn("%s: duty-ns is not defind\n", __func__);
}
rc = of_property_read_s32(of_node, "gpio5-pwm-period-ns", &data->period_ns);
if (rc)
{
pr_warn("%s: gpio5-pwm-period-ns is not defind\n", __func__);
}
rc = of_property_read_s32(of_node, "gpio5-pwm-state", &data->state);
if (rc)
{
pr_warn("%s: gpio5-pwm-state is not defind\n", __func__);
}
//rc = pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
//if (rc)
//{
// pr_err("%s: failed to change pwm config\n", __func__);
// goto error;
//}
data->fan_en_gpio = of_get_named_gpio(of_node, "qcom,fan-en-gpio", 0);
if (data->fan_en_gpio < 0){
pr_err("%s: get qcom,fan-en-gpio failed\n", __func__);
goto error;
}
if (gpio_is_valid(data->fan_en_gpio)) {
ret = gpio_request(data->fan_en_gpio, "quectel_red_led_en");
if (ret) {
pr_err("%s: Unable to request fan_en_gpio [%d]\n", __func__,data->fan_en_gpio);
goto error;
}
} else {
pr_err("%s: Invalid fan_en_gpio [%d]!\n", __func__,data->fan_en_gpio);
ret = -EINVAL;
goto err_free_red_led_en;
}
data->fan_int_gpio = of_get_named_gpio(of_node, "qcom,fan-fg-gpio", 0);
if (data->fan_int_gpio < 0){
pr_err("%s: get qcom,fan-int-gpio failed\n", __func__);
goto error;
}
if (gpio_request(data->fan_int_gpio, "fan_fg_int_gpio") != 0) {
gpio_free(data->fan_int_gpio);
pr_err("%s: get data->fan_int_gpio failed\n", __func__);
goto error;
}
gpio_direction_input(data->fan_int_gpio);
data->fan_irq = gpio_to_irq(data->fan_int_gpio);
rc = request_threaded_irq(data->fan_irq, NULL,
fan_irq_handler,
IRQF_TRIGGER_RISING |IRQF_ONESHOT,
"gpio5-pwm", data);
if (rc)
{
pr_err("%s: request irq err = %d\n",__func__,rc);
gpio_free(data->fan_int_gpio);
goto error;
}
printk("%s: fan_irq= %d\n",__func__,data->fan_irq);
//if (1 == data->state)
//{
// rc = pwm_enable(data->pwm_dev);
// if (rc)
// {
// pr_err("%s: failed to enable pwm\n", __func__);
// goto error;
// }
//}
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
pwm_disable(data->pwm_dev);
data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
printk("xxh ------------- %s end!\n",__func__);
return 0;
err_free_red_led_en:
if (gpio_is_valid(data->fan_en_gpio))
gpio_free(data->fan_en_gpio);
error:
kfree(data);
return rc;
}
static int gpio5_pwm_remove(struct platform_device *pdev)
{
if (data->state)
pwm_disable(data->pwm_dev);
kfree(data);
return 0;
}
static void gpio5_pwm_shutdown(struct platform_device *pdev)
{
if (data->state)
pwm_disable(data->pwm_dev);
pr_err("gpio5_pwm_shutdown\n");
}
/*
static struct class_attribute gpio_class_attrs[] =
{
__ATTR(state, 0664, state_show, state_store),
__ATTR(duty, 0664, duty_show, duty_store),
__ATTR(period, 0664, period_show, period_store),
__ATTR(speed, 0664, speed_show, NULL),
__ATTR(thermal_mode, 0664, thermal_show, thermal_store),
__ATTR(en_backlight, 0664, en_backlight_show, en_backlight_store),
__ATTR(hdmi_state, 0664, hdmi_state_show, hdmi_state_store),
__ATTR(dp_state, 0664, dp_state_show, dp_state_store),
__ATTR_NULL,
};
*/
static struct attribute *gpio5_pwm_attrs[] = {
&class_attr_state.attr,
&class_attr_duty.attr,
&class_attr_period.attr,
&class_attr_speed.attr,
&class_attr_thermal.attr,
&class_attr_en_backlight.attr,
&class_attr_secondary_en_backlight.attr,
&class_attr_hdmi_state.attr,
&class_attr_dp_state.attr,
NULL,
};
/*
static struct class gpio5_pwm_class =
{
.name = "gpio5_pwm2",
.class_groups = gpio5_pwm_attrs,
};
*/
ATTRIBUTE_GROUPS(gpio5_pwm);
static const struct of_device_id pwm_match_table[] =
{
{ .compatible = "gpio5-pwm", },
{},
};
/*
#ifdef CONFIG_PM
static const struct dev_pm_ops fan_pwm_dev_pm_ops = {
.suspend = fan_pwm_suspend,
.resume = fan_pwm_resume,
};
#endif
*/
static struct platform_driver gpio5_pwm_driver =
{
.driver = {
.name = "gpio5-pwm",
.of_match_table = pwm_match_table,
.owner = THIS_MODULE,
#ifdef CONFIG_PM
//.pm = &fan_pwm_dev_pm_ops,
#endif
},
.probe = gpio5_pwm_probe,
.remove = gpio5_pwm_remove,
.shutdown = gpio5_pwm_shutdown,
};
static int __init gpio5_pwm_init(void)
{
int rc = 0;
printk("[kevin]%s: %d\n", __func__,__LINE__);
gpio5_pwm_class.name = "gpio5_pwm2";
gpio5_pwm_class.class_groups = gpio5_pwm_groups;
rc = class_register(&gpio5_pwm_class);
if (0 == rc)
{
platform_driver_register(&gpio5_pwm_driver);
printk("[kevin]%s: %d\n", __func__,__LINE__);
}
return rc;
}
static void __exit gpio5_pwm_exit(void)
{
platform_driver_unregister(&gpio5_pwm_driver);
class_unregister(&gpio5_pwm_class);
}
module_init(gpio5_pwm_init);
module_exit(gpio5_pwm_exit);
MODULE_LICENSE("GPL");

View File

@@ -64,4 +64,4 @@ obj-$(CONFIG_OPEN_DICE) += open-dice.o
obj-$(CONFIG_QSEECOM_PROXY) += qseecom_proxy.o
obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o
obj-$(CONFIG_PROFILER) += profiler.o
obj-$(CONFIG_QRC) += qrc/
obj-y += ayn/

6
drivers/misc/ayn/Kconfig Executable file
View File

@@ -0,0 +1,6 @@
# to add sprd vsp configs in the future
config KEY_CHECK
tristate "M0 M1 driver"
config SHELL_ADC
tristate "shell adc driver"

1
drivers/misc/ayn/Makefile Executable file
View File

@@ -0,0 +1 @@
obj-y += gpio.o

437
drivers/misc/ayn/gpio.c Executable file
View File

@@ -0,0 +1,437 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/kobject.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
#include <mydebug.h>
#define GPIO_NUM_MAX 4
struct gpio_info{
char name[64];
int pin;
int direction;
int out_def;
};
static struct gpio_info all_gpio_pin[GPIO_NUM_MAX]={
{
.name = "mcu_boot",
.pin = MCU_BOOT,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_reset",
.pin = MCU_RESET,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_pwr",
.pin = MCU_PWR,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_uart_pwr",
.pin = MCU_UART_PWR,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
};
static void rs_gpio_request(void)
{
int ret;
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if (gpio_is_valid(all_gpio_pin[index].pin)) {
ret = gpio_request(all_gpio_pin[index].pin, all_gpio_pin[index].name);
if (ret < 0) {
KERNEL_INFO("Unable to request gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
if(all_gpio_pin[index].direction == GPIO_DIR_IN){
ret = gpio_direction_input(all_gpio_pin[index].pin);
if (ret < 0) {
KERNEL_INFO("Unable to set direction in for gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
} else {
ret = gpio_direction_output(all_gpio_pin[index].pin, all_gpio_pin[index].out_def);
if (ret < 0) {
KERNEL_INFO("Unable to set direction out for gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
}
ret = gpio_export(all_gpio_pin[index].pin, 1); // /sys/class/gpio/gpiox/
if (ret < 0) {
KERNEL_INFO("Unable to export gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
KERNEL_INFO("request gpio%d success ret=%d\n", all_gpio_pin[index].pin, ret);
}
}
}
static void rs_gpio_free(void)
{
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if (gpio_is_valid(all_gpio_pin[index].pin)) {
gpio_unexport(all_gpio_pin[index].pin);
gpio_free(all_gpio_pin[index].pin);
KERNEL_INFO("free gpio%d success\n", all_gpio_pin[index].pin);
}
}
}
void rs_gpio_set(int pin, int value)
{
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if(all_gpio_pin[index].pin != pin)
continue;
if (gpio_is_valid(all_gpio_pin[index].pin)) {
gpio_set_value(all_gpio_pin[index].pin, value);
KERNEL_INFO("name:%s %d", all_gpio_pin[index].name, value);
}
break;
}
}
EXPORT_SYMBOL(rs_gpio_set);
int rs_gpio_get(int pin)
{
int index;
int value = -1;
for(index=0; index<GPIO_NUM_MAX; index++){
if(all_gpio_pin[index].pin != pin)
continue;
if (gpio_is_valid(all_gpio_pin[index].pin)) {
value = gpio_get_value(all_gpio_pin[index].pin);
}
break;
}
KERNEL_INFO("name:%s %d", all_gpio_pin[index].name, value);
return value;
}
EXPORT_SYMBOL(rs_gpio_get);
int gpio_index = 0;
// 当用户试图从设备空间读取数据时,调用这个函数
ssize_t rs_gpio_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
{
ssize_t cnt = 0;
char send_msg[64]={0};
if(gpio_index >= GPIO_NUM_MAX){
KERNEL_INFO("ERROR gpio=%d when reading!!\n", gpio_index);
return -EFAULT;
}
sprintf(send_msg, "%u\n", gpio_get_value(all_gpio_pin[gpio_index].pin));;
cnt = copy_to_user(buf, send_msg, sizeof(send_msg));// 将内核空间的数据copy到用户空间
if(cnt){
KERNEL_INFO("ERROR occur when reading!!\n");
return -EFAULT;
}
KERNEL_INFO("name:%s %d", all_gpio_pin[gpio_index].name, gpio_get_value(all_gpio_pin[gpio_index].pin));
return cnt;
}
// 当用户往设备文件写数据时,调用这个函数
// counter 10 intervalgpio 30 intervaladc 30 bufsize 2048 gpiopin 总个数 0 122 124 threshold
ssize_t rs_gpio_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
{
int gpio = 0;
KERNEL_INFO("%s\n", ubuf);
if(!strncmp(ubuf, "SETGPIO ", 8) && count > 8){ // SETGPIO 1 1
gpio = ubuf[8];
if(gpio < GPIO_NUM_MAX){
if (gpio_is_valid(all_gpio_pin[gpio].pin)) {
if(count > 10){
gpio_set_value(all_gpio_pin[gpio].pin, ubuf[10]);
} else {
KERNEL_INFO("error pin=%d", all_gpio_pin[gpio].pin);
}
}
} else {
KERNEL_INFO("error gpio=%d", gpio);
}
}else if(!strncmp(ubuf, "GETGPIO ", 8) && count > 8){ // GETGPIO 1
gpio = ubuf[8];
if(gpio < GPIO_NUM_MAX){
gpio_index = gpio;
}
}
return count;
}
// File opertion 结构体,我们通过这个结构体建立应用程序到内核之间操作的映射
static struct file_operations file_oprts = {
.owner = THIS_MODULE,
.read = rs_gpio_read,
.write = rs_gpio_write,
};
#define DEVICE_NAME "rsgpio" // Device 名称,对应/dev下的目录名称
static struct miscdevice rs_gpio_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &file_oprts
};
/*
static int rs_gpio_suspend(void)
{
bright = 0;
printk("bright %d gpio_get_value(88) = %d \n",bright,gpio_get_value(88));
return 0;
}
static int rs_gpio_resume(void)
{
bright = 1;
printk("bright %d gpio_get_value(88) = %d \n",bright,gpio_get_value(88));
return 0;
}
static struct dev_pm_ops rs_gpio_pm_ops = {
.suspend = rs_gpio_suspend,
.resume = rs_gpio_resume,
};
*/
static void mcu_power_on(void)
{
// Init MCU_Boot = 0 && MCU_Reset = 1'b0
if (gpio_is_valid(MCU_BOOT)) {
gpio_direction_output(MCU_BOOT, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_LOW);
}
// Enable MCU 3.3
if (gpio_is_valid(MCU_PWR)) {
gpio_direction_output(MCU_PWR, GPIO_OUT_HIGH);
msleep(20);
}
// Enable OE of AW3911 - Level shifter
if (gpio_is_valid(MCU_UART_PWR)) {
gpio_direction_output(MCU_UART_PWR, GPIO_OUT_HIGH);
msleep(20);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_HIGH);
}
}
static void mcu_power_off(void)
{
//rs_gpio_set(MCU_PWR, GPIO_OUT_LOW);
if (gpio_is_valid(MCU_PWR)) {
gpio_direction_output(MCU_PWR, GPIO_OUT_LOW);
}
//rs_gpio_set(MCU_UART_PWR, GPIO_OUT_LOW);
if (gpio_is_valid(MCU_UART_PWR)) {
gpio_direction_output(MCU_UART_PWR, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_BOOT)) {
gpio_direction_output(MCU_BOOT, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_LOW);
}
}
/*
// android_print 表示Android层LOG打印开关
#ifdef CONFIG_ANDROID_LOG_CLOSED
static char android_print = 0; // 0表示不打印user版本的默认不打印
#else
static char android_print = 1; // 1表示打印
#endif
#define LOG_SEEK_OFFSET 8*1024*1024
#define LOG_PATH "/dev/block/sde65"
static int rwdev(char* buf, int len, int flag) {
struct file *log_filp;
mm_segment_t old_fs;
int length=0;
log_filp=filp_open(LOG_PATH,O_RDWR,0);
if(IS_ERR(log_filp)){
KERNEL_ERROR("open %s err:%d !\n",LOG_PATH,PTR_ERR(log_filp));
return -1;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
log_filp->f_op->llseek(log_filp, LOG_SEEK_OFFSET, SEEK_SET);
if(flag==0)
length=vfs_read(log_filp, buf, len, &log_filp->f_pos);
else
length=vfs_write(log_filp, buf, len, &log_filp->f_pos);
set_fs(old_fs);
return length;
}
static int get_log_enable(void) {
char buf[2];
int length = rwdev(buf, 2, 0);
if(length < 2) {
KERNEL_ERROR("get_log_enable %s err!\n",LOG_PATH);
return -1;
}
if(buf[0] == '1') {
if(buf[1] == '1') {
return 1;
} else {
return 0;
}
} else {
return android_print;
}
}
static int write_log_enable(char is_enable) {
char buf[2] = {'1',is_enable};
int length = rwdev(buf, 2, 1);
if(length < 2) {
KERNEL_ERROR("write_log_enable %s err!\n",LOG_PATH);
return -1;
}
return 0;
}
*/
// 添加节点控制
static ssize_t sysfs_set_driver_ctl(struct device *dev, struct device_attribute *attr, const char *ubuf, size_t size)
{
KERNEL_ERROR("cmd_write:%s", ubuf);
if(!strncmp(ubuf, "mcupower ", 9) && size > 9){
if(ubuf[9] == '1'){
// 打开MCU的电
mcu_power_on();
} else {
// 关掉MCU的电
mcu_power_off();
}
} else if(!strncmp(ubuf, "logenable ", 10) && size > 10){
if(ubuf[10] == '1'){
//write_log_enable('1');
} else {
//write_log_enable('0');
}
} else {
KERNEL_ERROR(KERN_ERR "muxcmd error for cmd %s", ubuf);
}
return size;
}
static ssize_t sysfs_get_driver_ctl(struct device *dev, struct device_attribute *attr, char *ubuf)
{
ssize_t size = 0;//sprintf(ubuf, "%d", get_log_enable());
KERNEL_ERROR("cmd_read: size=%d, ubuf=%s", size, ubuf);
return size;
}
static DEVICE_ATTR(driver_ctl, 0644, sysfs_get_driver_ctl, sysfs_set_driver_ctl);
static void rs_gpio_shutdown(struct platform_device *device)
{
KERNEL_INFO("done!");
}
static int rs_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret = misc_register(&rs_gpio_misc_device);
if (ret) {
KERNEL_INFO("rs_gpio: Unable to register misc device ret=%d\n", ret);
}
rs_gpio_request();
device_create_file(dev, &dev_attr_driver_ctl);
//mcu_power_on();
KERNEL_INFO("\n");
return ret;
}
static int __exit rs_gpio_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
KERNEL_INFO("\n");
rs_gpio_free();
misc_deregister(&rs_gpio_misc_device);
device_remove_file(dev, &dev_attr_driver_ctl);
return 0;
}
static struct platform_driver rs_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DEVICE_NAME,
//.pm = &rs_gpio_pm_ops,
},
.shutdown = rs_gpio_shutdown,
.probe = rs_gpio_probe,
.remove = rs_gpio_remove,
};
static struct platform_device rs_gpio_dev = {
.name = DEVICE_NAME,
.id = -1,
};
int __init rs_gpio_init(void)
{
platform_device_register(&rs_gpio_dev);
platform_driver_register(&rs_gpio_driver);
KERNEL_INFO("driver init success!!\n");
return 0;
}
void __exit rs_gpio_exit(void)
{
platform_device_unregister(&rs_gpio_dev);
platform_driver_unregister(&rs_gpio_driver);
KERNEL_INFO("driver %s removed\n", DEVICE_NAME);
}
module_init(rs_gpio_init);
module_exit(rs_gpio_exit);
MODULE_AUTHOR("kevin");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIO driver");

View File

@@ -23,7 +23,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/slot-gpio.h>
#include <mydebug.h>
#include "core.h"
#include "crypto.h"
#include "host.h"
@@ -277,7 +277,7 @@ EXPORT_SYMBOL(mmc_of_parse_clk_phase);
int mmc_of_parse(struct mmc_host *host)
{
struct device *dev = host->parent;
u32 bus_width, drv_type, cd_debounce_delay_ms;
u32 bus_width, drv_type;
int ret;
if (!dev || !dev_fwnode(dev))
@@ -329,14 +329,14 @@ int mmc_of_parse(struct mmc_host *host)
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
if (device_property_read_u32(dev, "cd-debounce-delay-ms",
&cd_debounce_delay_ms))
cd_debounce_delay_ms = 200;
&host->cd_debounce_delay_ms))
host->cd_debounce_delay_ms = 200;
if (device_property_read_bool(dev, "broken-cd"))
host->caps |= MMC_CAP_NEEDS_POLL;
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
cd_debounce_delay_ms * 1000);
host->cd_debounce_delay_ms * 1000);
if (!ret)
dev_info(host->parent, "Got CD GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
@@ -662,6 +662,7 @@ EXPORT_SYMBOL(mmc_remove_host);
*/
void mmc_free_host(struct mmc_host *host)
{
cancel_delayed_work_sync(&host->detect);
mmc_pwrseq_free(host);
put_device(&host->class_dev);
}

View File

@@ -920,11 +920,14 @@ static int mmc_sd_get_ro(struct mmc_host *host)
return ro;
}
#define MMC_SD_INIT_RETRIES 1
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
bool reinit)
{
int err;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
if (!reinit) {
/*
@@ -953,7 +956,25 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
* Fetch switch information from card. Note, sd3_bus_mode can change if
* voltage switch outcome changes, so do this always.
*/
#ifdef MMC_SD_INIT_RETRIES
for (retries = 1; retries <= 3; retries++) {
err = mmc_read_switch(card);
if (!err) {
if (retries > 1) {
printk(KERN_WARNING
"%s: recovered\n",
mmc_hostname(host));
}
break;
} else {
printk(KERN_WARNING
"%s: read switch failed (attempt %d)\n",
mmc_hostname(host), retries);
}
}
#else
err = mmc_read_switch(card);
#endif
if (err)
return err;
@@ -1604,14 +1625,33 @@ static int mmc_sd_alive(struct mmc_host *host)
*/
static void mmc_sd_detect(struct mmc_host *host)
{
int err;
int err = 0;
#ifdef MMC_SD_INIT_RETRIES
int retries = 5;
#endif
mmc_get_card(host->card, NULL);
/*
* Just check if our card has been removed.
*/
#ifdef MMC_SD_INIT_RETRIES
while(retries) {
err = mmc_send_status(host->card, NULL);
if (err) {
retries--;
udelay(5);
continue;
}
break;
}
if (!retries) {
printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n",
__func__, mmc_hostname(host), err);
}
#else
err = _mmc_detect_card_removed(host);
#endif
mmc_put_card(host->card, NULL);
@@ -1739,6 +1779,9 @@ static int mmc_sd_suspend(struct mmc_host *host)
static int _mmc_sd_resume(struct mmc_host *host)
{
int err = 0;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
mmc_claim_host(host);
@@ -1746,7 +1789,23 @@ static int _mmc_sd_resume(struct mmc_host *host)
goto out;
mmc_power_up(host, host->card->ocr);
#ifdef MMC_SD_INIT_RETRIES
retries = 5;
while (retries) {
err = mmc_sd_init_card(host, host->card->ocr, host->card);
if (err) {
printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
mmc_hostname(host), err, retries);
mdelay(5);
retries--;
continue;
}
break;
}
#else
err = mmc_sd_init_card(host, host->card->ocr, host->card);
#endif
mmc_card_clr_suspended(host->card);
out:
@@ -1823,6 +1882,9 @@ int mmc_attach_sd(struct mmc_host *host)
{
int err;
u32 ocr, rocr;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
WARN_ON(!host->claimed);
@@ -1864,9 +1926,27 @@ int mmc_attach_sd(struct mmc_host *host)
/*
* Detect and init the card.
*/
#ifdef MMC_SD_INIT_RETRIES
retries = 5;
while (retries) {
err = mmc_sd_init_card(host, rocr, NULL);
if (err) {
retries--;
continue;
}
break;
}
if (!retries) {
printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
mmc_hostname(host), err);
goto err;
}
#else
err = mmc_sd_init_card(host, rocr, NULL);
if (err)
goto err;
#endif
mmc_release_host(host);
err = mmc_add_card(host->card);

View File

@@ -1216,6 +1216,8 @@ int mmc_attach_sdio(struct mmc_host *host)
* Detect and init the card.
*/
err = mmc_sdio_init_card(host, rocr, NULL);
if (err)
err = mmc_sdio_init_card(host, rocr, NULL);
if (err)
goto err;

View File

@@ -4716,7 +4716,7 @@ static int sdhci_msm_setup_ice_clk(struct sdhci_msm_host *msm_host,
static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host)
{
msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
//msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
}
/* RUMI W/A for SD card */

View File

@@ -57,6 +57,13 @@
#define WLS_FW_BUF_SIZE 128
#define DEFAULT_RESTRICT_FCC_UA 1000000
//#undef dev_dbg
//#define dev_dbg dev_err
//#undef pr_debug
//#define pr_debug pr_info
extern void bcl_configure_bcl(int e);
enum psy_type {
PSY_TYPE_BATTERY,
PSY_TYPE_USB,
@@ -95,6 +102,9 @@ enum battery_property_id {
BATT_RESISTANCE,
BATT_POWER_NOW,
BATT_POWER_AVG,
BATT_SMB_PRESENT,
BATT_SMB1_CURRENT,
BATT_SMB2_CURRENT,
BATT_PROP_MAX,
};
@@ -112,6 +122,9 @@ enum usb_property_id {
USB_TEMP,
USB_REAL_TYPE,
USB_TYPEC_COMPLIANT,
USB_TYPEC_ORIENTATION,
USB_TYPEC_DISABLE,
USB_CHARGE_NOW,
USB_PROP_MAX,
};
@@ -297,6 +310,7 @@ static const int usb_prop_map[USB_PROP_MAX] = {
[USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
[USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE,
[USB_TEMP] = POWER_SUPPLY_PROP_TEMP,
[USB_CHARGE_NOW]= POWER_SUPPLY_PROP_CHARGE_NOW,
};
static const int wls_prop_map[WLS_PROP_MAX] = {
@@ -325,6 +339,8 @@ static const char * const qc_power_supply_wls_type_text[] = {
"Unknown", "BPP", "EPP", "HPP"
};
static struct battery_chg_dev *g_bcdev = NULL;
static RAW_NOTIFIER_HEAD(hboost_notifier);
int register_hboost_event_notifier(struct notifier_block *nb)
@@ -728,6 +744,7 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data,
static struct power_supply_desc usb_psy_desc;
int temp_type;
static void battery_chg_update_usb_type_work(struct work_struct *work)
{
struct battery_chg_dev *bcdev = container_of(work,
@@ -748,6 +765,14 @@ static void battery_chg_update_usb_type_work(struct work_struct *work)
pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]);
if (pst->prop[USB_ADAP_TYPE]!=temp_type){
if(pst->prop[USB_ADAP_TYPE] >= POWER_SUPPLY_USB_TYPE_PD){
bcl_configure_bcl(0);
}else{
bcl_configure_bcl(1);
}
temp_type = pst->prop[USB_ADAP_TYPE];
}
switch (pst->prop[USB_ADAP_TYPE]) {
case POWER_SUPPLY_USB_TYPE_SDP:
usb_psy_desc.type = POWER_SUPPLY_TYPE_USB;
@@ -1111,6 +1136,7 @@ static enum power_supply_property usb_props[] = {
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_USB_TYPE,
POWER_SUPPLY_PROP_TEMP,
};
@@ -1701,6 +1727,81 @@ static ssize_t usb_typec_compliant_show(struct class *c,
}
static CLASS_ATTR_RO(usb_typec_compliant);
static ssize_t usb_charge_now_store(struct class *c,
struct class_attribute *attr,
const char *buf, size_t count)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
u32 val;
int rc;
if (kstrtou32(buf, 0, &val))
return -EINVAL;
rc = write_property_id(bcdev, pst, USB_CHARGE_NOW, val);
if (rc < 0)
return rc;
printk(KERN_ERR "jaden usb_charge_now_store val :%d\n",val);
return count;
}
static CLASS_ATTR_WO(usb_charge_now);
static ssize_t usb_typec_orientation_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(bcdev, pst, USB_TYPEC_ORIENTATION);
if (rc < 0)
return rc;
printk(KERN_ERR "jaden usb_typec_orientation_show\n");
//kernel_power_off();
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[USB_TYPEC_ORIENTATION]);
}
static CLASS_ATTR_RO(usb_typec_orientation);
static ssize_t usb_typec_disable_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(bcdev, pst, USB_TYPEC_DISABLE);
printk(KERN_ERR "jaden usb_typec_disable_show\n");
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[USB_TYPEC_DISABLE]);
}
static CLASS_ATTR_RO(usb_typec_disable);
int usb_typec_disable(void)
{
struct psy_state *pst = &g_bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(g_bcdev, pst, USB_TYPEC_DISABLE);
printk(KERN_ERR "jaden usb_typec_disable\n");
if (rc < 0)
return rc;
return 0;
}
EXPORT_SYMBOL(usb_typec_disable);
static ssize_t usb_real_type_show(struct class *c,
struct class_attribute *attr, char *buf)
{
@@ -1750,7 +1851,8 @@ static ssize_t restrict_cur_show(struct class *c, struct class_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%u\n", bcdev->restrict_fcc_ua);
}
static CLASS_ATTR_RW(restrict_cur);
//static CLASS_ATTR_RW(restrict_cur);
static struct class_attribute class_attr_restrict_cur = __ATTR(restrict_cur, 0664, restrict_cur_show, restrict_cur_store);
static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr,
const char *buf, size_t count)
@@ -1780,7 +1882,8 @@ static ssize_t restrict_chg_show(struct class *c, struct class_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->restrict_chg_en);
}
static CLASS_ATTR_RW(restrict_chg);
//static CLASS_ATTR_RW(restrict_chg);
static struct class_attribute class_attr_restrict_chg = __ATTR(restrict_chg, 0664, restrict_chg_show, restrict_chg_store);
static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr,
const char *buf, size_t count)
@@ -1917,6 +2020,54 @@ static ssize_t resistance_show(struct class *c,
return scnprintf(buf, PAGE_SIZE, "%u\n", pst->prop[BATT_RESISTANCE]);
}
static CLASS_ATTR_RO(resistance);
static ssize_t smb1_current_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB1_CURRENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB1_CURRENT]);
}
static CLASS_ATTR_RO(smb1_current);
static ssize_t smb2_current_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB2_CURRENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB2_CURRENT]);
}
static CLASS_ATTR_RO(smb2_current);
static ssize_t smb_present_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB_PRESENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB_PRESENT]);
}
static CLASS_ATTR_RO(smb_present);
static ssize_t soh_show(struct class *c, struct class_attribute *attr,
char *buf)
@@ -1974,6 +2125,12 @@ static struct attribute *battery_class_attrs[] = {
&class_attr_restrict_cur.attr,
&class_attr_usb_real_type.attr,
&class_attr_usb_typec_compliant.attr,
&class_attr_usb_typec_orientation.attr,
&class_attr_usb_typec_disable.attr,
&class_attr_usb_charge_now.attr,
&class_attr_smb_present.attr,
&class_attr_smb1_current.attr,
&class_attr_smb2_current.attr,
NULL,
};
ATTRIBUTE_GROUPS(battery_class);
@@ -2320,8 +2477,13 @@ static int battery_chg_probe(struct platform_device *pdev)
rc = battery_chg_parse_dt(bcdev);
if (rc < 0) {
dev_err(dev, "Failed to parse dt rc=%d\n", rc);
goto error;
msleep(500);
dev_err(dev, "Failed to parse dt rc=%d delay 500ms retry", rc);
rc = battery_chg_parse_dt(bcdev);
if (rc < 0) {
dev_err(dev, "Failed to parse dt rc=%d", rc);
goto error;
};
}
bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA;
@@ -2353,6 +2515,7 @@ static int battery_chg_probe(struct platform_device *pdev)
bcdev->wls_fw_update_time_ms = WLS_FW_UPDATE_TIME_MS;
battery_chg_add_debugfs(bcdev);
bcdev->notify_en = false;
g_bcdev = bcdev;
battery_chg_notify_enable(bcdev);
device_init_wakeup(bcdev->dev, true);
schedule_work(&bcdev->usb_type_work);

View File

@@ -25,6 +25,8 @@
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/types.h>
#include <linux/pinctrl/consumer.h>
#include <linux/string.h>
#define REG_SIZE_PER_LPG 0x100
#define LPG_BASE "lpg-base"
@@ -164,6 +166,12 @@ static const int clk_period_ns_hi_res[NUM_PWM_HI_RES_CLK] = {976562, 30517, 52,
static const int clk_prediv[NUM_CLK_PREDIV] = {1, 3, 5, 6};
static const int pwm_exponent[NUM_PWM_EXP] = {0, 1, 2, 3, 4, 5, 6, 7};
static struct pinctrl *pmk8550_gpio5_pinctrl;
static struct pinctrl_state *pinctrl_state_active;
static struct pinctrl_state *pinctrl_state_suspend;
#define PINCTRL_STATE_ACTIVE "active"
#define PINCTRL_STATE_SUSPEND "suspend"
struct lpg_ramp_config {
u16 step_ms;
u8 pause_hi_count;
@@ -1506,11 +1514,33 @@ static int qpnp_lpg_pwm_apply(struct pwm_chip *pwm_chip, struct pwm_device *pwm,
if (state->enabled != pwm->state.enabled) {
if (state->enabled) {
if(!strncmp(pwm->label, "qcom,mdss_dsi", 13)){
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
printk(KERN_ERR "Darcy pwm enabled pmk8550_gpio5_pinctrl not use %d\n",rc);
} else if(pmk8550_gpio5_pinctrl && pinctrl_state_active){
rc = pinctrl_select_state(pmk8550_gpio5_pinctrl, pinctrl_state_active);
if(rc<0){
printk(KERN_ERR "Failed to select pmk8550_gpio5 pin to active state\n");
}
}
}
rc = qpnp_lpg_pwm_enable(pwm->chip, pwm);
if (rc < 0)
return rc;
} else {
qpnp_lpg_pwm_disable(pwm->chip, pwm);
if(!strncmp(pwm->label, "qcom,mdss_dsi", 13)){
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
printk(KERN_ERR "Darcy pwm Disable pmk8550_gpio5_pinctrl not use %d\n",rc);
}else if(pmk8550_gpio5_pinctrl && pinctrl_state_suspend){
rc = pinctrl_select_state(pmk8550_gpio5_pinctrl, pinctrl_state_suspend);
if(rc<0){
printk(KERN_ERR "Failed to select pmk8550_gpio5 pin to suspend state\n");
}
}
}
}
pwm->state.enabled = state->enabled;
@@ -2013,6 +2043,29 @@ static int qpnp_lpg_probe(struct platform_device *pdev)
return -ENOMEM;
chip->dev = &pdev->dev;
//pmk8550_gpio5_pinctrl add
pmk8550_gpio5_pinctrl = devm_pinctrl_get(chip->dev);
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
dev_err(&pdev->dev,"Darcy Target does not use pinctrl %d\n",rc);
goto err_pinctrl_get;
}
pinctrl_state_active = pinctrl_lookup_state(pmk8550_gpio5_pinctrl,PINCTRL_STATE_ACTIVE);
if(IS_ERR_OR_NULL(pinctrl_state_active)){
rc = PTR_ERR(pinctrl_state_active);
dev_err(&pdev->dev,"Darcy Can not lookup %s pinstate %d\n",PINCTRL_STATE_ACTIVE,rc);
}
pinctrl_state_suspend = pinctrl_lookup_state(pmk8550_gpio5_pinctrl,PINCTRL_STATE_SUSPEND);
if(IS_ERR_OR_NULL(pinctrl_state_suspend)){
rc = PTR_ERR(pinctrl_state_suspend);
dev_err(&pdev->dev,"Darcy Can not lookup %s pinstate %d\n",PINCTRL_STATE_SUSPEND,rc);
}
err_pinctrl_get:
//end
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) {
dev_err(chip->dev, "Getting regmap failed\n");

View File

@@ -107,7 +107,7 @@ out:
return pivot;
}
/*
static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
{
int index;
@@ -143,7 +143,7 @@ static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
}
pr_cont("\n");
}
*/
static void compute_irq_stat(struct work_struct *work)
{
unsigned int count;
@@ -249,7 +249,7 @@ static void compute_irq_stat(struct work_struct *work)
}
}
print_irq_stat(wdog_dd);
//print_irq_stat(wdog_dd);
atomic_xchg(&wdog_dd->irq_counts_running, 0);
}

View File

@@ -153,6 +153,7 @@ struct bcl_device {
};
static struct bcl_device *bcl_devices[MAX_PERPH_COUNT];
struct bcl_device *bcl_perph_temp;
static int bcl_device_ct;
static int bcl_read_register(struct bcl_device *bcl_perph, int16_t reg_offset,
@@ -918,6 +919,15 @@ static void bcl_configure_bcl_peripheral(struct bcl_device *bcl_perph)
bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7));
}
void bcl_configure_bcl(int enable)
{
if (enable)
bcl_write_register(bcl_perph_temp, BCL_MONITOR_EN, BIT(7));
else
bcl_write_register(bcl_perph_temp, BCL_MONITOR_EN, 0);
}
EXPORT_SYMBOL(bcl_configure_bcl);
static int bcl_remove(struct platform_device *pdev)
{
int i = 0;
@@ -949,6 +959,7 @@ static int bcl_probe(struct platform_device *pdev)
if (!bcl_devices[bcl_device_ct])
return -ENOMEM;
bcl_perph = bcl_devices[bcl_device_ct];
bcl_perph_temp = bcl_perph;
bcl_perph->dev = &pdev->dev;
bcl_perph->regmap = dev_get_regmap(pdev->dev.parent, NULL);

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2024, check mcu data. All rights reserved.
*/
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/ipc_logging.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/qcom-geni-se.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/suspend.h>/*包含#include <linux/freezer.h>freezer.h又包含"set_freezable"*/
#include <linux/ioctl.h>
#include <linux/pinctrl/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/kthread.h>
#include <linux/kernel.h>/*printk()*/
#include <linux/sched.h>
#include <mydebug.h>
#define FRAME_POS_HEAD_1 0
#define FRAME_POS_HEAD_2 1
#define FRAME_POS_HEAD_3 2
#define FRAME_POS_HEAD_4 3
#define FRAME_POS_SEQ 4
#define FRAME_POS_CMD 5
#define FRAME_POS_LEN_LOW 6
#define FRAME_POS_LEN_HIGHT 7
#define FRAME_POS_DATA_0 8
#define FRAME_POS_DATA_1 9
#define FRAME_POS_DATA_2 10
#define FRAME_DATA_MIN 9
#define FRAME_HEAD_1 0xA5
#define FRAME_HEAD_2 0xD3
#define FRAME_HEAD_3 0x5A
#define FRAME_HEAD_4 0x3D
#define CMD_COMMOD 0x01
#define CMD_STATUS 0x02
#define CMD_IAP 0x03
#define USART_RX_BUFF_MAX 2048//20480
#define PRINT_DATA_BUFF_MAX 1024//4096
int dataLen(char* buf)
{
return (char)( (buf[FRAME_POS_LEN_LOW]&0xff) | ((buf[FRAME_POS_LEN_HIGHT] >> 8)&0xFF) );
}
int checkSumDataLen(char* buf)
{
return dataLen(buf) + 4; // data + seq length1 length2 cmd
}
int calcChecksum(char* buf)
{
int index = 0;
int sum = 0;// 定义为byte时最高位变成符号导致最高位为1时检验和为负数变成检验不通过
int len = checkSumDataLen(buf) + FRAME_POS_SEQ;
for(index=FRAME_POS_SEQ; index<len; index++){
sum ^= buf[index];
//KERNEL_ERROR("sum=0x%x, buf[%d]=%x", (sum&0xFF), index, buf[index]);
}
//KERNEL_ERROR("sum=0x%x", (sum&0xFF));
return (sum&0xFF);
}
int headFrontErr = 0;
int headErr = 0;
int checksumErr = 0;
int dataLenErr = 0;
EXPORT_SYMBOL(headFrontErr);
EXPORT_SYMBOL(headErr);
EXPORT_SYMBOL(checksumErr);
EXPORT_SYMBOL(dataLenErr);
void printfData(char errno, char *buffer, int len)
{
static char data[PRINT_DATA_BUFF_MAX] = {0};
int index = 0, pos = 0;
for(index=0; index<len; index++){
sprintf(data+pos, "%02x ", buffer[index]);
pos += 3;
if(pos >= PRINT_DATA_BUFF_MAX - 3){
break;
}
}
if(errno > 0){
KERNEL_ERROR("errno=%d, length=%d, data=%s", errno, len, data);
}
}
static char WORK_INTERVAL = 30;
static char buffer_ring[USART_RX_BUFF_MAX] = {0};
static int recvDataLen = 0;
static int procDataLen = 0;
void copyMcuData(char *buf, int length)
{
// 接收数据
if(length >= USART_RX_BUFF_MAX){
KERNEL_ERROR("length=%d, too much data, bigger %d.", length, USART_RX_BUFF_MAX);
recvDataLen = 0;
}
if(length + recvDataLen >= USART_RX_BUFF_MAX){
KERNEL_ERROR("recvDataLen=%d, length=%d, Complete verification, bigger %d.", recvDataLen, length, USART_RX_BUFF_MAX);
recvDataLen = 0;
}
memcpy(buffer_ring+recvDataLen, buf, length);
recvDataLen += length;
WORK_INTERVAL = 30;
//printfData(1, buffer_ring, recvDataLen);
}
EXPORT_SYMBOL(copyMcuData);
static void processMcuData(void)
{
char *p = buffer_ring;
int len = recvDataLen;
int checksum = 0;
int pkt_len = 0;
char printfEn = 0;
if(recvDataLen == procDataLen){
WORK_INTERVAL = 100;
return;
}
// 需要处理的数据
while(len >= FRAME_DATA_MIN){
// find a packet HEAD
while ( len >= FRAME_POS_HEAD_4 && \
((p[FRAME_POS_HEAD_1] != FRAME_HEAD_1 || \
p[FRAME_POS_HEAD_2] != FRAME_HEAD_2 || \
p[FRAME_POS_HEAD_3] != FRAME_HEAD_3 || \
p[FRAME_POS_HEAD_4] != FRAME_HEAD_4))) {
++p;
--len;
++headFrontErr;
++procDataLen;
}
if(len <= 0){ // 数据查找完成,但没有找到帧头
headErr++;
printfEn = 1;
KERNEL_ERROR("can`t find a packet HEAD\n");
break;
}
if(len < FRAME_DATA_MIN){ // 数据查找完成,但数据不完整
dataLenErr++;
printfEn = 2;
KERNEL_ERROR("The data is not complete frame. len=%d\n", len);
break;
}
pkt_len = p[FRAME_POS_LEN_LOW] + (p[FRAME_POS_LEN_HIGHT] << 8);
if(len < pkt_len + FRAME_DATA_MIN){
dataLenErr++;
printfEn = 3;
KERNEL_ERROR("The data is not complete frame. len=%d, pkt_len=%d\n", len, pkt_len);
break;
}
checksum = calcChecksum(p);
if(p[pkt_len + FRAME_POS_DATA_0] == checksum){
//KERNEL_ERROR("packet checksum Successful.");
printfEn = 5;
p += pkt_len + FRAME_DATA_MIN;
len -= pkt_len + FRAME_DATA_MIN; // 数据减少一帧
procDataLen += pkt_len + FRAME_DATA_MIN;
} else {
printfEn = 4;
checksumErr++;
p += FRAME_POS_HEAD_4;
len -= FRAME_POS_HEAD_4; // 数据减少帧头
procDataLen += FRAME_POS_HEAD_4;
KERNEL_ERROR("packet checksum=%x(%x) failed, skip it, len=%d", checksum, p[pkt_len + FRAME_POS_DATA_0], pkt_len);
}
if(printfEn != 5){
printfData(printfEn, buffer_ring, len);
printfEn = 0;
}
if(procDataLen >= USART_RX_BUFF_MAX){
procDataLen = 0;
}
}
}
static struct task_struct *detect_task = NULL;
static int readstatus_work(void *arg)
{
KERNEL_ERROR("readstatus_work start!\n");
set_freezable();
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(WORK_INTERVAL));
if (kthread_freezable_should_stop(NULL))
break;
processMcuData();
}
KERNEL_ERROR("readstatus_work exit!\n");
return 0;
}
void checkMcuRemove(void)
{
KERNEL_ERROR("remove task");
if(detect_task != NULL){
kthread_stop(detect_task);
detect_task = NULL;
}
}
EXPORT_SYMBOL(checkMcuRemove);
void checkMcuInit(void)
{
KERNEL_ERROR("init task");
if(detect_task){
KERNEL_ERROR("mcu detect: kthread_create init");
return;
}
detect_task = kthread_run(readstatus_work, NULL, "mcu detect");
if (IS_ERR(detect_task)) {
KERNEL_ERROR("mcu detect: kthread_create failed");
return;
}
}
EXPORT_SYMBOL(checkMcuInit);

View File

@@ -32,6 +32,8 @@
#include <linux/ioctl.h>
#include <linux/pinctrl/consumer.h>
#include <linux/dma-mapping.h>
#include <mydebug.h>
#include "check_mcu_data.c"
#include <uapi/linux/msm_geni_serial.h>
#include <soc/qcom/boot_stats.h>
@@ -181,7 +183,10 @@ static bool con_enabled = IS_ENABLED(CONFIG_SERIAL_MSM_GENI_CONSOLE_DEFAULT_ENAB
*/
#define POLL_ITERATIONS 1000
#define IPC_LOG_MSG(ctx, x...) ipc_log_string(ctx, x)
#define IPC_LOG_MSG(ctx, x...) do { \
if (ctx) \
ipc_log_string(ctx, x); \
} while (0)
#define DMA_RX_BUF_SIZE (2048)
#define UART_CONSOLE_RX_WM (2)
@@ -1013,6 +1018,8 @@ static void dump_ipc(struct uart_port *uport, void *ipc_ctx, char *prefix,
char data[DATA_BYTES_PER_LINE * 3];
int len = 0;
if (!ipc_ctx)
return;
len = min(size, DATA_BYTES_PER_LINE);
hex_dump_to_buffer(string, len, DATA_BYTES_PER_LINE, 1, buf,
sizeof(buf), false);
@@ -2958,6 +2965,10 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport)
__func__, ret);
}
static int checkmcuEn = 0;
extern void copyMcuData(char *buf, int length);
extern void checkMcuInit(void);
extern void checkMcuRemove(void);
static int handle_rx_hs(struct uart_port *uport,
unsigned int rx_fifo_wc,
unsigned int rx_last_byte_valid,
@@ -2989,6 +3000,9 @@ static int handle_rx_hs(struct uart_port *uport,
}
uport->icount.rx += ret;
tty_flip_buffer_push(tport);
if(checkmcuEn == 1 && uport->line == 1){
copyMcuData((char *)msm_port->rx_fifo, rx_bytes);
}
dump_ipc(uport, msm_port->ipc_log_rx, "Rx", (char *)msm_port->rx_fifo, 0,
rx_bytes);
return ret;
@@ -3111,6 +3125,50 @@ exit_handle_tx:
return 0;
}
extern int headFrontErr;
extern int headErr;
extern int checksumErr;
extern int dataLenErr;
static ssize_t checkmcu_show(struct device *dev, struct device_attribute *attr, char *ubuf)
{
ssize_t size = sprintf(ubuf, "%d", checkmcuEn);
KERNEL_ERROR("cmd_read: checkmcuEn=%d, headFrontErr=%d, headErr=%d, checksumErr=%d, dataLenErr=%d", checkmcuEn, headFrontErr, headErr, checksumErr, dataLenErr);
return size;
}
static void msm_geni_serial_debug_init(struct uart_port *uport, bool console);
static ssize_t checkmcu_store(struct device *dev, struct device_attribute *attr, const char *ubuf, size_t size)
{
struct uart_port *uport;
struct msm_geni_serial_port *port = get_port_from_line(1, false);
if (IS_ERR_OR_NULL(port))
return size;
uport = &port->uport;
KERNEL_ERROR("cmd_write:%s", ubuf);
if(!strncmp(ubuf, "checkmcu ", 9) && size > 9){
if(ubuf[9] == '1'){
checkMcuInit();
checkmcuEn = 1;
if (IS_ERR_OR_NULL(port->dbg))
msm_geni_serial_debug_init(uport, 0);
} else {
checkmcuEn = 0;
checkMcuRemove();
if (!IS_ERR_OR_NULL(port->dbg)){
port->dbg = NULL;
debugfs_remove(port->dbg);
}
}
} else {
KERNEL_ERROR(KERN_ERR "muxcmd error for cmd %s", ubuf);
}
return size;
}
static DEVICE_ATTR_RW(checkmcu);
/*
* msm_geni_find_wakeup_byte() - Checks if wakeup byte is present
* in rx buffer
@@ -3255,6 +3313,9 @@ static int msm_geni_serial_handle_dma_rx(struct uart_port *uport, bool drop_rx)
uport->icount.rx += rx_bytes_copied;
tty_flip_buffer_push(tport);
if(checkmcuEn == 1 && uport->line == 1){
copyMcuData((char *)msm_port->rx_buf, rx_bytes_copied);
}
dump_ipc(uport, msm_port->ipc_log_rx, "DMA Rx",
(char *)msm_port->rx_buf, 0, rx_bytes_copied);
/*
@@ -5162,9 +5223,9 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
* To Disable PM runtime API that will make ioctl based
* vote_clock_on/off optional and rely on system PM
*/
dev_port->pm_auto_suspend_disable =
of_property_read_bool(pdev->dev.of_node,
"qcom,auto-suspend-disable");
dev_port->pm_auto_suspend_disable = 1;
//of_property_read_bool(pdev->dev.of_node,
//"qcom,auto-suspend-disable");
if (is_console) {
dev_port->handle_rx = handle_rx_console;
@@ -5203,8 +5264,8 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
device_create_file(uport->dev, &dev_attr_hs_uart_operation);
device_create_file(uport->dev, &dev_attr_hs_uart_version);
device_create_file(uport->dev, &dev_attr_capture_kpi);
msm_geni_serial_debug_init(uport, is_console);
device_create_file(uport->dev, &dev_attr_checkmcu);
//msm_geni_serial_debug_init(uport, is_console);
dev_port->port_setup = false;
dev_port->uart_error = UART_ERROR_DEFAULT;
@@ -5269,6 +5330,12 @@ static int msm_geni_serial_remove(struct platform_device *pdev)
device_remove_file(port->uport.dev, &dev_attr_xfer_mode);
device_remove_file(port->uport.dev, &dev_attr_ver_info);
device_remove_file(port->uport.dev, &dev_attr_capture_kpi);
device_remove_file(port->uport.dev, &dev_attr_checkmcu);
if(checkmcuEn == 1){
checkMcuRemove();
}
if (!IS_ERR_OR_NULL(port->dbg))
debugfs_remove(port->dbg);
dev_info(&pdev->dev, "%s driver removed %d\n", __func__, true);

View File

@@ -100,7 +100,7 @@ obj-$(CONFIG_SMBFS_COMMON) += smbfs_common/
obj-$(CONFIG_CIFS) += cifs/
obj-$(CONFIG_SMB_SERVER) += ksmbd/
obj-$(CONFIG_HPFS_FS) += hpfs/
obj-$(CONFIG_NTFS_FS) += ntfs/
obj-y += ntfs/
obj-$(CONFIG_NTFS3_FS) += ntfs3/
obj-$(CONFIG_UFS_FS) += ufs/
obj-$(CONFIG_EFS_FS) += efs/

View File

@@ -36,7 +36,7 @@ struct mipi_dsi_msg {
u16 flags;
size_t tx_len;
const void *tx_buf;
void *tx_buf;
size_t rx_len;
void *rx_buf;

View File

@@ -81,8 +81,9 @@
#define EXTCON_DOCK 60
#define EXTCON_JIG 61
#define EXTCON_MECHANICAL 62
#define EXTCON_DEMO_A 63
#define EXTCON_NUM 63
#define EXTCON_NUM 64
/*
* Define the properties of supported external connectors.

View File

@@ -338,6 +338,7 @@ struct mmc_host {
u32 max_current_330;
u32 max_current_300;
u32 max_current_180;
u32 cd_debounce_delay_ms;
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */

173
include/mydebug.h Executable file
View File

@@ -0,0 +1,173 @@
/*
* mydebug.h
*
* ============================================================================
* Copyright (c) 2011 Liuwen
*
* Use of this software is controlled by the terms and conditions found in the
* license agreement under which this software has been supplied or provided.
* ============================================================================
*/
#ifndef KERNEL_DEBUG_H
#define KERNEL_DEBUG_H
//GPIO的文件
#include <linux/io.h>
#include <linux/of_gpio.h>
// 音效ic
// 触摸
#define GPIO_DIR_OUT 0
#define GPIO_DIR_IN 1
#define GPIO_OUT_LOW 0
#define GPIO_OUT_HIGH 1
#define MCU_PWR (301+99) // 400 GPIO_99
#define MCU_BOOT (301+1) // 302 GPIO_1
#define MCU_RESET (301) // 301 GPIO_0
#define MCU_UART_PWR (301+12) // 313 GPIO_12
enum MCU_POWER_STATUS {
MCU_POWER_UNKNOWN,
MCU_POWER_ON,
MCU_POWER_OFF,
};
extern void rs_gpio_set(int pin, int value);
extern int rs_gpio_get(int pin);
#define KERNEL_PRINTK 1
#define KERNEL_PROCESS 0
#define UNWIND_BACKTRACE 0
#ifdef KERNEL_GLOBALS
unsigned int all_times;//no define static, static only at the some file.
EXPORT_SYMBOL(all_times);
#else
extern unsigned int all_times;
#endif // KERNEL_GLOBALS
//#define MY_FILE (__FILE__ + 78 + 6)
#define MY_FILE __FILE__
// static unsigned int file_times;
#if UNWIND_BACKTRACE
#ifdef KERNEL_MODULE
#define MY_UNWIND_BACKTRACE()
#else
extern void my_unwind_backtrace(struct pt_regs *, struct task_struct *);//my_unwind_backtrace(NULL, NULL);
#define MY_UNWIND_BACKTRACE() my_unwind_backtrace(NULL, NULL)
#endif
#else
#define MY_UNWIND_BACKTRACE()
#endif /*UNWIND_BACKTRACE*/
#if KERNEL_PROCESS
#include <linux/sched.h>
//#include <asm/current.h>
#include <asm/thread_info.h>//arch/arm/include/asm/thread_info.h
#define cpu_context current_thread_info()->cpu_context
#define process_info(level) \
do{ \
printk(level "state=%s, Process_num=%d, pid=%d, tgid=%d, syscall=%d, cpu=%d, \
cpu_context.pc=0x%x, r4=0x%x, r5=0x%x, r6=0x%x, r7=0x%x, r8=0x%x, r9=0x%x, sl=0x%x, fp=0x%x, sp=0x%x, extra[0]=0x%x, extra[1]=0x%x", \
(current->state == -1)?"unrunnable":(current->state > -1 && current->state == 0)? "runnable":"stopped" ,\
current->flags, current->pid, current->tgid, current_thread_info()->syscall,\
current_thread_info()->cpu, cpu_context.pc, \
cpu_context.r4, cpu_context.r5, \
cpu_context.r6, cpu_context.r7, \
cpu_context.r8, cpu_context.r9, \
cpu_context.sl, cpu_context.fp, \
cpu_context.sp, cpu_context.extra[0], cpu_context.extra[1]); \
}while(0)
//cpu_context.cpu_context.extra
#else
#define process_info(level) do { } while(0)
#endif // KERNEL_PROCESS
#define driver_printk(level, format, args...) \
do{ \
printk(level "Odin [%s:%s():%d]" format, \
MY_FILE, __FUNCTION__, __LINE__, ##args); \
process_info(level); \
MY_UNWIND_BACKTRACE(); \
printk(level "\n"); \
}while(0)
#if KERNEL_PRINTK
#define KERNEL_DEBUG(format , args...) driver_printk(KERN_DEBUG, format, ## args)
#else
#define KERNEL_DEBUG(format , args...)
#endif
#define KERNEL_INFO(format , args...) driver_printk(KERN_INFO, format, ## args)
#define KERNEL_WARN(format , args...) driver_printk(KERN_WARNING, format, ## args)
#define KERNEL_ERROR(format , args...) driver_printk(KERN_ERR, format, ## args)
#endif// KERNEL_DEBUG_H
/*
printk后便
%p(raw pointer)
%pF可打印函数指针的函数名和偏移地址
%pf只打印函数指针的函数名
printk("%pf",func[0]->action);
my_Set
%pM打印冒号分隔的MAC地址
%pm打印MAC地址的16进制无分隔
printk("%pM %pm\n", mac, mac) willprint:
2c:00:1d:00:1b:00 2c001d001b00
%I4打印无前导0的IPv4地址%i4打印冒号分隔的IPv4地址
%I6打印无前导0的IPv6地址%i6打印冒号分隔的IPv6地址
printk("%pI4 %pi4\n", ip, ip) will print:
127.0.0.1 127:0:0:1
*/
//#define KERNEL_GLOBALS
//#include <mydebug.h>
//KERNEL_DEBUG("\n\n");

View File

@@ -732,7 +732,7 @@ config LOG_BUF_SHIFT
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
range 12 25 if !H8300
range 12 19 if H8300
default 17
default 22
depends on PRINTK
help
Select the minimal kernel log buffer size as a power of 2.
@@ -741,6 +741,7 @@ config LOG_BUF_SHIFT
by "log_buf_len" boot parameter.
Examples:
22 => 4096 KB
17 => 128 KB
16 => 64 KB
15 => 32 KB

View File

@@ -28,12 +28,14 @@ else
TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
fi
if test -z "$KBUILD_BUILD_USER"; then
LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
# LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
LINUX_COMPILE_BY="Thor"
else
LINUX_COMPILE_BY=$KBUILD_BUILD_USER
fi
if test -z "$KBUILD_BUILD_HOST"; then
LINUX_COMPILE_HOST=`uname -n`
# LINUX_COMPILE_HOST=`uname -n`
LINUX_COMPILE_HOST="ayn_server"
else
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
fi

View File

@@ -1008,17 +1008,50 @@ struct avc_node *avc_compute_av(struct selinux_state *state,
rcu_read_lock();
return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
}
extern int selinux_enforce_start;
static noinline int avc_denied(struct selinux_state *state,
u32 ssid, u32 tsid,
u16 tclass, u32 requested,
u8 driver, u8 xperm, unsigned int flags,
struct av_decision *avd)
{
u32 scontext_len;
u32 tcontext_len;
u32 enable = enforcing_enabled(state);
char *scontext = NULL;
char *tcontext = NULL;
if (flags & AVC_STRICT)
return -EACCES;
if (security_sid_to_context(state, ssid, &scontext, &scontext_len)){
if (enforcing_enabled(state) &&
} else {
if(selinux_enforce_start) {
if(strstr(scontext, "untrusted_app") != NULL) {
if (security_sid_to_context(state, tsid, &tcontext, &tcontext_len)){
if(!(avd->flags & AVD_FLAGS_PERMISSIVE)){
//printk(KERN_EMERG "%s scontext1:%s %d\n",__func__, scontext,avd->flags);
kfree(scontext);
return -EACCES;
}
} else {
if(strstr(tcontext, "pservice") == NULL) {
if(!(avd->flags & AVD_FLAGS_PERMISSIVE)){
//printk(KERN_EMERG "%s scontext:%s tcontext:%s %d\n",__func__, scontext, tcontext,avd->flags);
kfree(scontext);
kfree(tcontext);
return -EACCES;
}
}
}
}
enable = 0;
}
kfree(tcontext);
kfree(scontext);
}
if (enable &&
!(avd->flags & AVD_FLAGS_PERMISSIVE))
return -EACCES;
@@ -1183,7 +1216,6 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
{
struct av_decision avd;
int rc, rc2;
rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
&avd);

View File

@@ -64,6 +64,7 @@ enum sel_inos {
SEL_STATUS, /* export current status using mmap() */
SEL_POLICY, /* allow userspace to read the in kernel policy */
SEL_VALIDATE_TRANS, /* compute validatetrans decision */
SEL_ENFORCE_START, /* compute validatetrans decision */
SEL_INO_NEXT, /* The next inode number to use */
};
@@ -200,6 +201,51 @@ static const struct file_operations sel_enforce_ops = {
.write = sel_write_enforce,
.llseek = generic_file_llseek,
};
int selinux_enforce_start = 0;
static ssize_t sel_read_enforce_start(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char tmpbuf[TMPBUFLEN];
ssize_t length;
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
selinux_enforce_start);
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
}
static ssize_t sel_write_enforce_start(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *page = NULL;
ssize_t length;
int new_value;
if (count >= PAGE_SIZE)
return -ENOMEM;
/* No partial writes. */
if (*ppos != 0)
return -EINVAL;
page = memdup_user_nul(buf, count);
if (IS_ERR(page))
return PTR_ERR(page);
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
goto out;
selinux_enforce_start = !!new_value;
out:
kfree(page);
return length;
}
static const struct file_operations sel_enforce_start_ops = {
.read = sel_read_enforce_start,
.write = sel_write_enforce_start,
};
static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
@@ -2080,6 +2126,8 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
S_IWUGO},
[SEL_ENFORCE_START] = {"enforce_start", &sel_enforce_start_ops,
S_IRUGO|S_IWUSR},
/* last one */ {""}
};