msm5.15: Import ayn changes from ayn_8550.xz (01/18/2026)
Signed-off-by: AnierinB <anierin@evolution-x.org>
This commit is contained in:
9
arch/arm64/configs/vendor/kalama_GKI.config
vendored
9
arch/arm64/configs/vendor/kalama_GKI.config
vendored
@@ -32,7 +32,7 @@ CONFIG_CORESIGHT_TGU=m
|
|||||||
CONFIG_CORESIGHT_TPDA=m
|
CONFIG_CORESIGHT_TPDA=m
|
||||||
CONFIG_CORESIGHT_TPDM=m
|
CONFIG_CORESIGHT_TPDM=m
|
||||||
CONFIG_CPU_IDLE_GOV_QCOM_LPM=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=m
|
||||||
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
||||||
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
||||||
@@ -135,10 +135,16 @@ CONFIG_NL80211_TESTMODE=y
|
|||||||
CONFIG_NOP_USB_XCEIV=m
|
CONFIG_NOP_USB_XCEIV=m
|
||||||
CONFIG_NVMEM_SPMI_SDAM=m
|
CONFIG_NVMEM_SPMI_SDAM=m
|
||||||
CONFIG_NVME_CORE=m
|
CONFIG_NVME_CORE=m
|
||||||
|
CONFIG_ETHERNET=y
|
||||||
|
CONFIG_NET_VENDOR_QUALCOMM=y
|
||||||
# CONFIG_NVME_HWMON is not set
|
# CONFIG_NVME_HWMON is not set
|
||||||
# CONFIG_NVME_MULTIPATH is not set
|
# CONFIG_NVME_MULTIPATH is not set
|
||||||
# CONFIG_NXP_TJA11XX_PHY is not set
|
# CONFIG_NXP_TJA11XX_PHY is not set
|
||||||
CONFIG_PCI_MSM=m
|
CONFIG_PCI_MSM=m
|
||||||
|
CONFIG_PAGE_POOL=y
|
||||||
|
CONFIG_PHYLINK=y
|
||||||
|
#CONFIG_QPS615=y
|
||||||
|
#CONFIG_r8168=y
|
||||||
CONFIG_PDR_INDICATION_NOTIF_TIMEOUT=9000
|
CONFIG_PDR_INDICATION_NOTIF_TIMEOUT=9000
|
||||||
CONFIG_PHY_QCOM_UFS=m
|
CONFIG_PHY_QCOM_UFS=m
|
||||||
CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m
|
CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m
|
||||||
@@ -561,3 +567,4 @@ CONFIG_VIRT_DRIVERS=y
|
|||||||
# CONFIG_WFX is not set
|
# CONFIG_WFX is not set
|
||||||
# CONFIG_WILC1000_SDIO is not set
|
# CONFIG_WILC1000_SDIO is not set
|
||||||
# CONFIG_WILC1000_SPI is not set
|
# CONFIG_WILC1000_SPI is not set
|
||||||
|
CONFIG_PWM_PM=m
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ CONFIG_CORESIGHT_TGU=m
|
|||||||
CONFIG_CORESIGHT_TPDA=m
|
CONFIG_CORESIGHT_TPDA=m
|
||||||
CONFIG_CORESIGHT_TPDM=m
|
CONFIG_CORESIGHT_TPDM=m
|
||||||
CONFIG_CPU_IDLE_GOV_QCOM_LPM=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=m
|
||||||
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
||||||
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ CONFIG_DRM_TTM=y
|
|||||||
# CONFIG_EEPROM_93XX46 is not set
|
# CONFIG_EEPROM_93XX46 is not set
|
||||||
# CONFIG_EEPROM_AT25 is not set
|
# CONFIG_EEPROM_AT25 is not set
|
||||||
# CONFIG_EZX_PCAP is not set
|
# CONFIG_EZX_PCAP is not set
|
||||||
|
CONFIG_FB=y
|
||||||
CONFIG_FB_CMDLINE=y
|
CONFIG_FB_CMDLINE=y
|
||||||
CONFIG_GENERIC_PINCONF=y
|
CONFIG_GENERIC_PINCONF=y
|
||||||
CONFIG_GH_ARM64_DRV=y
|
CONFIG_GH_ARM64_DRV=y
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
## Variant setup
|
## Variant setup
|
||||||
MSM_ARCH=kalama
|
MSM_ARCH=kalama
|
||||||
VARIANTS=(consolidate gki)
|
VARIANTS=gki
|
||||||
[ -z "${VARIANT}" ] && VARIANT=consolidate
|
[ -z "${VARIANT}" ] && VARIANT=gki
|
||||||
|
|
||||||
ABL_SRC=bootable/bootloader/edk2
|
ABL_SRC=bootable/bootloader/edk2
|
||||||
BOOT_IMAGE_HEADER_VERSION=4
|
BOOT_IMAGE_HEADER_VERSION=4
|
||||||
|
|||||||
@@ -184,6 +184,11 @@ static const struct __extcon_info {
|
|||||||
.id = EXTCON_MECHANICAL,
|
.id = EXTCON_MECHANICAL,
|
||||||
.name = "MECHANICAL",
|
.name = "MECHANICAL",
|
||||||
},
|
},
|
||||||
|
[EXTCON_DEMO_A] = {
|
||||||
|
.type = EXTCON_TYPE_MISC,
|
||||||
|
.id = EXTCON_DEMO_A,
|
||||||
|
.name = "EXTCON_DEMO_AENG",
|
||||||
|
},
|
||||||
|
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ config I2C_COMPAT
|
|||||||
|
|
||||||
config I2C_CHARDEV
|
config I2C_CHARDEV
|
||||||
tristate "I2C device interface"
|
tristate "I2C device interface"
|
||||||
|
default y
|
||||||
help
|
help
|
||||||
Say Y here to use i2c-* device files, usually found in the /dev
|
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
|
directory on your system. They make it possible to have user-space
|
||||||
|
|||||||
@@ -2425,6 +2425,7 @@ static int geni_i2c_suspend_late(struct device *device)
|
|||||||
pm_runtime_set_suspended(device);
|
pm_runtime_set_suspended(device);
|
||||||
pm_runtime_enable(device);
|
pm_runtime_enable(device);
|
||||||
}
|
}
|
||||||
|
pm_runtime_enable(device);
|
||||||
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
|
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
|
||||||
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret);
|
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1380,6 +1380,12 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
|
|||||||
SCALE_HW_CALIB_DEFAULT)
|
SCALE_HW_CALIB_DEFAULT)
|
||||||
[ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9,
|
[ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9,
|
||||||
SCALE_HW_CALIB_PM7_SMB_TEMP)
|
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,
|
[ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0,
|
||||||
SCALE_HW_CALIB_PM7_CHG_TEMP)
|
SCALE_HW_CALIB_PM7_CHG_TEMP)
|
||||||
[ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8,
|
[ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8,
|
||||||
|
|||||||
@@ -1666,6 +1666,7 @@ static int haptics_wait_brake_complete(struct haptics_chip *chip)
|
|||||||
|
|
||||||
t_lra_us = (chip->config.cl_t_lra_us) ?
|
t_lra_us = (chip->config.cl_t_lra_us) ?
|
||||||
chip->config.cl_t_lra_us : chip->config.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);
|
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;
|
brake_length_us += t_lra_us;
|
||||||
delay_us = t_lra_us / 2;
|
delay_us = t_lra_us / 2;
|
||||||
timeout = brake_length_us / delay_us + 1;
|
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 */
|
/* poll HPWR_DISABLED to guarantee the brake pattern has been played completely */
|
||||||
do {
|
do {
|
||||||
@@ -4065,6 +4066,8 @@ static int haptics_create_debugfs(struct haptics_chip *chip)
|
|||||||
|
|
||||||
debugfs_create_u32("fifo_empty_thresh", 0600, hap_dir,
|
debugfs_create_u32("fifo_empty_thresh", 0600, hap_dir,
|
||||||
&chip->config.fifo_empty_thresh);
|
&chip->config.fifo_empty_thresh);
|
||||||
|
debugfs_create_u32("user_vmax_mv", 0666, hap_dir,
|
||||||
|
&chip->config.vmax_mv);
|
||||||
chip->debugfs_dir = hap_dir;
|
chip->debugfs_dir = hap_dir;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -4341,7 +4344,7 @@ static int haptics_parse_per_effect_dt(struct haptics_chip *chip,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config->is_erm)
|
//if (!config->is_erm)
|
||||||
effect->auto_res_disable = of_property_read_bool(node,
|
effect->auto_res_disable = of_property_read_bool(node,
|
||||||
"qcom,wf-auto-res-disable");
|
"qcom,wf-auto-res-disable");
|
||||||
|
|
||||||
@@ -5591,8 +5594,9 @@ static int haptics_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
rc = haptics_hw_init(chip);
|
rc = haptics_hw_init(chip);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chip->dev, "Initialize HW failed, rc = %d\n", rc);
|
dev_err(chip->dev, "probe() Initialize HW failed, rc = %d\n", rc);
|
||||||
return rc;
|
if(rc != -EBUSY)
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_swr_supported(chip)) {
|
if (is_swr_supported(chip)) {
|
||||||
@@ -5600,7 +5604,8 @@ static int haptics_probe(struct platform_device *pdev)
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chip->dev, "Initialize swr slave regulator failed, rc = %d\n",
|
dev_err(chip->dev, "Initialize swr slave regulator failed, rc = %d\n",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
if(rc != -EBUSY)
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5610,7 +5615,8 @@ static int haptics_probe(struct platform_device *pdev)
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(chip->dev, "request fifo-empty IRQ failed, rc=%d\n",
|
dev_err(chip->dev, "request fifo-empty IRQ failed, rc=%d\n",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
if(rc != -EBUSY)
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&chip->play.lock);
|
mutex_init(&chip->play.lock);
|
||||||
@@ -5714,7 +5720,7 @@ static int haptics_ds_resume_config(struct device *dev)
|
|||||||
|
|
||||||
rc = haptics_hw_init(chip);
|
rc = haptics_hw_init(chip);
|
||||||
if (rc < 0) {
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,9 @@ config LEDS_QTI_FLASH
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called leds-qti-flash.
|
module will be called leds-qti-flash.
|
||||||
|
|
||||||
|
config PWM_PM
|
||||||
|
tristate "Support for PWM_PM"
|
||||||
|
|
||||||
config LEDS_QPNP_FLASH_V2
|
config LEDS_QPNP_FLASH_V2
|
||||||
tristate "Support for QPNP V2 Flash LEDs"
|
tristate "Support for QPNP V2 Flash LEDs"
|
||||||
depends on LEDS_CLASS && MFD_SPMI_PMIC
|
depends on LEDS_CLASS && MFD_SPMI_PMIC
|
||||||
|
|||||||
@@ -110,3 +110,4 @@ obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
|
|||||||
|
|
||||||
# LED Blink
|
# LED Blink
|
||||||
obj-y += blink/
|
obj-y += blink/
|
||||||
|
obj-$(CONFIG_PWM_PM) += gpio5_pwm.o
|
||||||
|
|||||||
550
drivers/leds/gpio5_pwm.c
Normal file
550
drivers/leds/gpio5_pwm.c
Normal 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");
|
||||||
|
|
||||||
@@ -64,4 +64,4 @@ obj-$(CONFIG_OPEN_DICE) += open-dice.o
|
|||||||
obj-$(CONFIG_QSEECOM_PROXY) += qseecom_proxy.o
|
obj-$(CONFIG_QSEECOM_PROXY) += qseecom_proxy.o
|
||||||
obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o
|
obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o
|
||||||
obj-$(CONFIG_PROFILER) += profiler.o
|
obj-$(CONFIG_PROFILER) += profiler.o
|
||||||
obj-$(CONFIG_QRC) += qrc/
|
obj-y += ayn/
|
||||||
6
drivers/misc/ayn/Kconfig
Executable file
6
drivers/misc/ayn/Kconfig
Executable 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
1
drivers/misc/ayn/Makefile
Executable file
@@ -0,0 +1 @@
|
|||||||
|
obj-y += gpio.o
|
||||||
437
drivers/misc/ayn/gpio.c
Executable file
437
drivers/misc/ayn/gpio.c
Executable 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");
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/mmc/card.h>
|
#include <linux/mmc/card.h>
|
||||||
#include <linux/mmc/slot-gpio.h>
|
#include <linux/mmc/slot-gpio.h>
|
||||||
|
#include <mydebug.h>
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
@@ -277,7 +277,7 @@ EXPORT_SYMBOL(mmc_of_parse_clk_phase);
|
|||||||
int mmc_of_parse(struct mmc_host *host)
|
int mmc_of_parse(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
struct device *dev = host->parent;
|
struct device *dev = host->parent;
|
||||||
u32 bus_width, drv_type, cd_debounce_delay_ms;
|
u32 bus_width, drv_type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!dev || !dev_fwnode(dev))
|
if (!dev || !dev_fwnode(dev))
|
||||||
@@ -329,14 +329,14 @@ int mmc_of_parse(struct mmc_host *host)
|
|||||||
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
||||||
|
|
||||||
if (device_property_read_u32(dev, "cd-debounce-delay-ms",
|
if (device_property_read_u32(dev, "cd-debounce-delay-ms",
|
||||||
&cd_debounce_delay_ms))
|
&host->cd_debounce_delay_ms))
|
||||||
cd_debounce_delay_ms = 200;
|
host->cd_debounce_delay_ms = 200;
|
||||||
|
|
||||||
if (device_property_read_bool(dev, "broken-cd"))
|
if (device_property_read_bool(dev, "broken-cd"))
|
||||||
host->caps |= MMC_CAP_NEEDS_POLL;
|
host->caps |= MMC_CAP_NEEDS_POLL;
|
||||||
|
|
||||||
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
|
ret = mmc_gpiod_request_cd(host, "cd", 0, false,
|
||||||
cd_debounce_delay_ms * 1000);
|
host->cd_debounce_delay_ms * 1000);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
dev_info(host->parent, "Got CD GPIO\n");
|
dev_info(host->parent, "Got CD GPIO\n");
|
||||||
else if (ret != -ENOENT && ret != -ENOSYS)
|
else if (ret != -ENOENT && ret != -ENOSYS)
|
||||||
@@ -662,6 +662,7 @@ EXPORT_SYMBOL(mmc_remove_host);
|
|||||||
*/
|
*/
|
||||||
void mmc_free_host(struct mmc_host *host)
|
void mmc_free_host(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
|
cancel_delayed_work_sync(&host->detect);
|
||||||
mmc_pwrseq_free(host);
|
mmc_pwrseq_free(host);
|
||||||
put_device(&host->class_dev);
|
put_device(&host->class_dev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -920,11 +920,14 @@ static int mmc_sd_get_ro(struct mmc_host *host)
|
|||||||
|
|
||||||
return ro;
|
return ro;
|
||||||
}
|
}
|
||||||
|
#define MMC_SD_INIT_RETRIES 1
|
||||||
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
|
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
|
||||||
bool reinit)
|
bool reinit)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
#ifdef MMC_SD_INIT_RETRIES
|
||||||
|
int retries;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!reinit) {
|
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
|
* Fetch switch information from card. Note, sd3_bus_mode can change if
|
||||||
* voltage switch outcome changes, so do this always.
|
* 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);
|
err = mmc_read_switch(card);
|
||||||
|
#endif
|
||||||
if (err)
|
if (err)
|
||||||
return 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)
|
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);
|
mmc_get_card(host->card, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just check if our card has been removed.
|
* 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);
|
err = _mmc_detect_card_removed(host);
|
||||||
|
#endif
|
||||||
|
|
||||||
mmc_put_card(host->card, NULL);
|
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)
|
static int _mmc_sd_resume(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
#ifdef MMC_SD_INIT_RETRIES
|
||||||
|
int retries;
|
||||||
|
#endif
|
||||||
|
|
||||||
mmc_claim_host(host);
|
mmc_claim_host(host);
|
||||||
|
|
||||||
@@ -1746,7 +1789,23 @@ static int _mmc_sd_resume(struct mmc_host *host)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mmc_power_up(host, host->card->ocr);
|
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);
|
err = mmc_sd_init_card(host, host->card->ocr, host->card);
|
||||||
|
#endif
|
||||||
mmc_card_clr_suspended(host->card);
|
mmc_card_clr_suspended(host->card);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1823,6 +1882,9 @@ int mmc_attach_sd(struct mmc_host *host)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
u32 ocr, rocr;
|
u32 ocr, rocr;
|
||||||
|
#ifdef MMC_SD_INIT_RETRIES
|
||||||
|
int retries;
|
||||||
|
#endif
|
||||||
|
|
||||||
WARN_ON(!host->claimed);
|
WARN_ON(!host->claimed);
|
||||||
|
|
||||||
@@ -1864,9 +1926,27 @@ int mmc_attach_sd(struct mmc_host *host)
|
|||||||
/*
|
/*
|
||||||
* Detect and init the card.
|
* 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);
|
err = mmc_sd_init_card(host, rocr, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto err;
|
goto err;
|
||||||
|
#endif
|
||||||
|
|
||||||
mmc_release_host(host);
|
mmc_release_host(host);
|
||||||
err = mmc_add_card(host->card);
|
err = mmc_add_card(host->card);
|
||||||
|
|||||||
@@ -1216,6 +1216,8 @@ int mmc_attach_sdio(struct mmc_host *host)
|
|||||||
* Detect and init the card.
|
* Detect and init the card.
|
||||||
*/
|
*/
|
||||||
err = mmc_sdio_init_card(host, rocr, NULL);
|
err = mmc_sdio_init_card(host, rocr, NULL);
|
||||||
|
if (err)
|
||||||
|
err = mmc_sdio_init_card(host, rocr, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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;
|
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
|
||||||
}
|
}
|
||||||
/* RUMI W/A for SD card */
|
/* RUMI W/A for SD card */
|
||||||
|
|||||||
@@ -57,6 +57,13 @@
|
|||||||
#define WLS_FW_BUF_SIZE 128
|
#define WLS_FW_BUF_SIZE 128
|
||||||
#define DEFAULT_RESTRICT_FCC_UA 1000000
|
#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 {
|
enum psy_type {
|
||||||
PSY_TYPE_BATTERY,
|
PSY_TYPE_BATTERY,
|
||||||
PSY_TYPE_USB,
|
PSY_TYPE_USB,
|
||||||
@@ -95,6 +102,9 @@ enum battery_property_id {
|
|||||||
BATT_RESISTANCE,
|
BATT_RESISTANCE,
|
||||||
BATT_POWER_NOW,
|
BATT_POWER_NOW,
|
||||||
BATT_POWER_AVG,
|
BATT_POWER_AVG,
|
||||||
|
BATT_SMB_PRESENT,
|
||||||
|
BATT_SMB1_CURRENT,
|
||||||
|
BATT_SMB2_CURRENT,
|
||||||
BATT_PROP_MAX,
|
BATT_PROP_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,6 +122,9 @@ enum usb_property_id {
|
|||||||
USB_TEMP,
|
USB_TEMP,
|
||||||
USB_REAL_TYPE,
|
USB_REAL_TYPE,
|
||||||
USB_TYPEC_COMPLIANT,
|
USB_TYPEC_COMPLIANT,
|
||||||
|
USB_TYPEC_ORIENTATION,
|
||||||
|
USB_TYPEC_DISABLE,
|
||||||
|
USB_CHARGE_NOW,
|
||||||
USB_PROP_MAX,
|
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_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||||
[USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE,
|
[USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE,
|
||||||
[USB_TEMP] = POWER_SUPPLY_PROP_TEMP,
|
[USB_TEMP] = POWER_SUPPLY_PROP_TEMP,
|
||||||
|
[USB_CHARGE_NOW]= POWER_SUPPLY_PROP_CHARGE_NOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int wls_prop_map[WLS_PROP_MAX] = {
|
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"
|
"Unknown", "BPP", "EPP", "HPP"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct battery_chg_dev *g_bcdev = NULL;
|
||||||
|
|
||||||
static RAW_NOTIFIER_HEAD(hboost_notifier);
|
static RAW_NOTIFIER_HEAD(hboost_notifier);
|
||||||
|
|
||||||
int register_hboost_event_notifier(struct notifier_block *nb)
|
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;
|
static struct power_supply_desc usb_psy_desc;
|
||||||
|
|
||||||
|
int temp_type;
|
||||||
static void battery_chg_update_usb_type_work(struct work_struct *work)
|
static void battery_chg_update_usb_type_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct battery_chg_dev *bcdev = container_of(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]);
|
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]) {
|
switch (pst->prop[USB_ADAP_TYPE]) {
|
||||||
case POWER_SUPPLY_USB_TYPE_SDP:
|
case POWER_SUPPLY_USB_TYPE_SDP:
|
||||||
usb_psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
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_NOW,
|
||||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||||
|
POWER_SUPPLY_PROP_CHARGE_NOW,
|
||||||
POWER_SUPPLY_PROP_USB_TYPE,
|
POWER_SUPPLY_PROP_USB_TYPE,
|
||||||
POWER_SUPPLY_PROP_TEMP,
|
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 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,
|
static ssize_t usb_real_type_show(struct class *c,
|
||||||
struct class_attribute *attr, char *buf)
|
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);
|
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,
|
static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr,
|
||||||
const char *buf, size_t count)
|
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);
|
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,
|
static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr,
|
||||||
const char *buf, size_t count)
|
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]);
|
return scnprintf(buf, PAGE_SIZE, "%u\n", pst->prop[BATT_RESISTANCE]);
|
||||||
}
|
}
|
||||||
static CLASS_ATTR_RO(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,
|
static ssize_t soh_show(struct class *c, struct class_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
@@ -1974,6 +2125,12 @@ static struct attribute *battery_class_attrs[] = {
|
|||||||
&class_attr_restrict_cur.attr,
|
&class_attr_restrict_cur.attr,
|
||||||
&class_attr_usb_real_type.attr,
|
&class_attr_usb_real_type.attr,
|
||||||
&class_attr_usb_typec_compliant.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,
|
NULL,
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(battery_class);
|
ATTRIBUTE_GROUPS(battery_class);
|
||||||
@@ -2320,8 +2477,13 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
rc = battery_chg_parse_dt(bcdev);
|
rc = battery_chg_parse_dt(bcdev);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
dev_err(dev, "Failed to parse dt rc=%d\n", rc);
|
msleep(500);
|
||||||
goto error;
|
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;
|
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;
|
bcdev->wls_fw_update_time_ms = WLS_FW_UPDATE_TIME_MS;
|
||||||
battery_chg_add_debugfs(bcdev);
|
battery_chg_add_debugfs(bcdev);
|
||||||
bcdev->notify_en = false;
|
bcdev->notify_en = false;
|
||||||
|
g_bcdev = bcdev;
|
||||||
battery_chg_notify_enable(bcdev);
|
battery_chg_notify_enable(bcdev);
|
||||||
device_init_wakeup(bcdev->dev, true);
|
device_init_wakeup(bcdev->dev, true);
|
||||||
schedule_work(&bcdev->usb_type_work);
|
schedule_work(&bcdev->usb_type_work);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/pinctrl/consumer.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#define REG_SIZE_PER_LPG 0x100
|
#define REG_SIZE_PER_LPG 0x100
|
||||||
#define LPG_BASE "lpg-base"
|
#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 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 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 {
|
struct lpg_ramp_config {
|
||||||
u16 step_ms;
|
u16 step_ms;
|
||||||
u8 pause_hi_count;
|
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 != pwm->state.enabled) {
|
||||||
if (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);
|
rc = qpnp_lpg_pwm_enable(pwm->chip, pwm);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
qpnp_lpg_pwm_disable(pwm->chip, pwm);
|
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;
|
pwm->state.enabled = state->enabled;
|
||||||
@@ -2013,6 +2043,29 @@ static int qpnp_lpg_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
chip->dev = &pdev->dev;
|
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);
|
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
|
||||||
if (!chip->regmap) {
|
if (!chip->regmap) {
|
||||||
dev_err(chip->dev, "Getting regmap failed\n");
|
dev_err(chip->dev, "Getting regmap failed\n");
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ out:
|
|||||||
|
|
||||||
return pivot;
|
return pivot;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
|
static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
@@ -143,7 +143,7 @@ static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
|
|||||||
}
|
}
|
||||||
pr_cont("\n");
|
pr_cont("\n");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static void compute_irq_stat(struct work_struct *work)
|
static void compute_irq_stat(struct work_struct *work)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
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);
|
atomic_xchg(&wdog_dd->irq_counts_running, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ struct bcl_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct bcl_device *bcl_devices[MAX_PERPH_COUNT];
|
static struct bcl_device *bcl_devices[MAX_PERPH_COUNT];
|
||||||
|
struct bcl_device *bcl_perph_temp;
|
||||||
static int bcl_device_ct;
|
static int bcl_device_ct;
|
||||||
|
|
||||||
static int bcl_read_register(struct bcl_device *bcl_perph, int16_t reg_offset,
|
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));
|
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)
|
static int bcl_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -949,6 +959,7 @@ static int bcl_probe(struct platform_device *pdev)
|
|||||||
if (!bcl_devices[bcl_device_ct])
|
if (!bcl_devices[bcl_device_ct])
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
bcl_perph = bcl_devices[bcl_device_ct];
|
bcl_perph = bcl_devices[bcl_device_ct];
|
||||||
|
bcl_perph_temp = bcl_perph;
|
||||||
bcl_perph->dev = &pdev->dev;
|
bcl_perph->dev = &pdev->dev;
|
||||||
|
|
||||||
bcl_perph->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
bcl_perph->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||||
|
|||||||
250
drivers/tty/serial/check_mcu_data.c
Executable file
250
drivers/tty/serial/check_mcu_data.c
Executable 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);
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/pinctrl/consumer.h>
|
#include <linux/pinctrl/consumer.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <mydebug.h>
|
||||||
|
#include "check_mcu_data.c"
|
||||||
#include <uapi/linux/msm_geni_serial.h>
|
#include <uapi/linux/msm_geni_serial.h>
|
||||||
#include <soc/qcom/boot_stats.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 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 DMA_RX_BUF_SIZE (2048)
|
||||||
#define UART_CONSOLE_RX_WM (2)
|
#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];
|
char data[DATA_BYTES_PER_LINE * 3];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
if (!ipc_ctx)
|
||||||
|
return;
|
||||||
len = min(size, DATA_BYTES_PER_LINE);
|
len = min(size, DATA_BYTES_PER_LINE);
|
||||||
hex_dump_to_buffer(string, len, DATA_BYTES_PER_LINE, 1, buf,
|
hex_dump_to_buffer(string, len, DATA_BYTES_PER_LINE, 1, buf,
|
||||||
sizeof(buf), false);
|
sizeof(buf), false);
|
||||||
@@ -2958,6 +2965,10 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport)
|
|||||||
__func__, ret);
|
__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,
|
static int handle_rx_hs(struct uart_port *uport,
|
||||||
unsigned int rx_fifo_wc,
|
unsigned int rx_fifo_wc,
|
||||||
unsigned int rx_last_byte_valid,
|
unsigned int rx_last_byte_valid,
|
||||||
@@ -2989,6 +3000,9 @@ static int handle_rx_hs(struct uart_port *uport,
|
|||||||
}
|
}
|
||||||
uport->icount.rx += ret;
|
uport->icount.rx += ret;
|
||||||
tty_flip_buffer_push(tport);
|
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,
|
dump_ipc(uport, msm_port->ipc_log_rx, "Rx", (char *)msm_port->rx_fifo, 0,
|
||||||
rx_bytes);
|
rx_bytes);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -3111,6 +3125,50 @@ exit_handle_tx:
|
|||||||
return 0;
|
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
|
* msm_geni_find_wakeup_byte() - Checks if wakeup byte is present
|
||||||
* in rx buffer
|
* 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;
|
uport->icount.rx += rx_bytes_copied;
|
||||||
tty_flip_buffer_push(tport);
|
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",
|
dump_ipc(uport, msm_port->ipc_log_rx, "DMA Rx",
|
||||||
(char *)msm_port->rx_buf, 0, rx_bytes_copied);
|
(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
|
* To Disable PM runtime API that will make ioctl based
|
||||||
* vote_clock_on/off optional and rely on system PM
|
* vote_clock_on/off optional and rely on system PM
|
||||||
*/
|
*/
|
||||||
dev_port->pm_auto_suspend_disable =
|
dev_port->pm_auto_suspend_disable = 1;
|
||||||
of_property_read_bool(pdev->dev.of_node,
|
//of_property_read_bool(pdev->dev.of_node,
|
||||||
"qcom,auto-suspend-disable");
|
//"qcom,auto-suspend-disable");
|
||||||
|
|
||||||
if (is_console) {
|
if (is_console) {
|
||||||
dev_port->handle_rx = handle_rx_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_operation);
|
||||||
device_create_file(uport->dev, &dev_attr_hs_uart_version);
|
device_create_file(uport->dev, &dev_attr_hs_uart_version);
|
||||||
device_create_file(uport->dev, &dev_attr_capture_kpi);
|
device_create_file(uport->dev, &dev_attr_capture_kpi);
|
||||||
|
device_create_file(uport->dev, &dev_attr_checkmcu);
|
||||||
msm_geni_serial_debug_init(uport, is_console);
|
//msm_geni_serial_debug_init(uport, is_console);
|
||||||
dev_port->port_setup = false;
|
dev_port->port_setup = false;
|
||||||
|
|
||||||
dev_port->uart_error = UART_ERROR_DEFAULT;
|
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_xfer_mode);
|
||||||
device_remove_file(port->uport.dev, &dev_attr_ver_info);
|
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_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);
|
debugfs_remove(port->dbg);
|
||||||
|
|
||||||
dev_info(&pdev->dev, "%s driver removed %d\n", __func__, true);
|
dev_info(&pdev->dev, "%s driver removed %d\n", __func__, true);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ obj-$(CONFIG_SMBFS_COMMON) += smbfs_common/
|
|||||||
obj-$(CONFIG_CIFS) += cifs/
|
obj-$(CONFIG_CIFS) += cifs/
|
||||||
obj-$(CONFIG_SMB_SERVER) += ksmbd/
|
obj-$(CONFIG_SMB_SERVER) += ksmbd/
|
||||||
obj-$(CONFIG_HPFS_FS) += hpfs/
|
obj-$(CONFIG_HPFS_FS) += hpfs/
|
||||||
obj-$(CONFIG_NTFS_FS) += ntfs/
|
obj-y += ntfs/
|
||||||
obj-$(CONFIG_NTFS3_FS) += ntfs3/
|
obj-$(CONFIG_NTFS3_FS) += ntfs3/
|
||||||
obj-$(CONFIG_UFS_FS) += ufs/
|
obj-$(CONFIG_UFS_FS) += ufs/
|
||||||
obj-$(CONFIG_EFS_FS) += efs/
|
obj-$(CONFIG_EFS_FS) += efs/
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ struct mipi_dsi_msg {
|
|||||||
u16 flags;
|
u16 flags;
|
||||||
|
|
||||||
size_t tx_len;
|
size_t tx_len;
|
||||||
const void *tx_buf;
|
void *tx_buf;
|
||||||
|
|
||||||
size_t rx_len;
|
size_t rx_len;
|
||||||
void *rx_buf;
|
void *rx_buf;
|
||||||
|
|||||||
@@ -81,8 +81,9 @@
|
|||||||
#define EXTCON_DOCK 60
|
#define EXTCON_DOCK 60
|
||||||
#define EXTCON_JIG 61
|
#define EXTCON_JIG 61
|
||||||
#define EXTCON_MECHANICAL 62
|
#define EXTCON_MECHANICAL 62
|
||||||
|
#define EXTCON_DEMO_A 63
|
||||||
|
|
||||||
#define EXTCON_NUM 63
|
#define EXTCON_NUM 64
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define the properties of supported external connectors.
|
* Define the properties of supported external connectors.
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ struct mmc_host {
|
|||||||
u32 max_current_330;
|
u32 max_current_330;
|
||||||
u32 max_current_300;
|
u32 max_current_300;
|
||||||
u32 max_current_180;
|
u32 max_current_180;
|
||||||
|
u32 cd_debounce_delay_ms;
|
||||||
|
|
||||||
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
|
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
|
||||||
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
|
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
|
||||||
|
|||||||
173
include/mydebug.h
Executable file
173
include/mydebug.h
Executable 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");
|
||||||
@@ -732,7 +732,7 @@ config LOG_BUF_SHIFT
|
|||||||
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
|
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
|
||||||
range 12 25 if !H8300
|
range 12 25 if !H8300
|
||||||
range 12 19 if H8300
|
range 12 19 if H8300
|
||||||
default 17
|
default 22
|
||||||
depends on PRINTK
|
depends on PRINTK
|
||||||
help
|
help
|
||||||
Select the minimal kernel log buffer size as a power of 2.
|
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.
|
by "log_buf_len" boot parameter.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
22 => 4096 KB
|
||||||
17 => 128 KB
|
17 => 128 KB
|
||||||
16 => 64 KB
|
16 => 64 KB
|
||||||
15 => 32 KB
|
15 => 32 KB
|
||||||
|
|||||||
@@ -28,12 +28,14 @@ else
|
|||||||
TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
|
TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
|
||||||
fi
|
fi
|
||||||
if test -z "$KBUILD_BUILD_USER"; then
|
if test -z "$KBUILD_BUILD_USER"; then
|
||||||
LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
|
# LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
|
||||||
|
LINUX_COMPILE_BY="Thor"
|
||||||
else
|
else
|
||||||
LINUX_COMPILE_BY=$KBUILD_BUILD_USER
|
LINUX_COMPILE_BY=$KBUILD_BUILD_USER
|
||||||
fi
|
fi
|
||||||
if test -z "$KBUILD_BUILD_HOST"; then
|
if test -z "$KBUILD_BUILD_HOST"; then
|
||||||
LINUX_COMPILE_HOST=`uname -n`
|
# LINUX_COMPILE_HOST=`uname -n`
|
||||||
|
LINUX_COMPILE_HOST="ayn_server"
|
||||||
else
|
else
|
||||||
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
|
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1008,17 +1008,50 @@ struct avc_node *avc_compute_av(struct selinux_state *state,
|
|||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
|
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,
|
static noinline int avc_denied(struct selinux_state *state,
|
||||||
u32 ssid, u32 tsid,
|
u32 ssid, u32 tsid,
|
||||||
u16 tclass, u32 requested,
|
u16 tclass, u32 requested,
|
||||||
u8 driver, u8 xperm, unsigned int flags,
|
u8 driver, u8 xperm, unsigned int flags,
|
||||||
struct av_decision *avd)
|
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)
|
if (flags & AVC_STRICT)
|
||||||
return -EACCES;
|
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))
|
!(avd->flags & AVD_FLAGS_PERMISSIVE))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
@@ -1183,7 +1216,6 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
|
|||||||
{
|
{
|
||||||
struct av_decision avd;
|
struct av_decision avd;
|
||||||
int rc, rc2;
|
int rc, rc2;
|
||||||
|
|
||||||
rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
|
rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
|
||||||
&avd);
|
&avd);
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ enum sel_inos {
|
|||||||
SEL_STATUS, /* export current status using mmap() */
|
SEL_STATUS, /* export current status using mmap() */
|
||||||
SEL_POLICY, /* allow userspace to read the in kernel policy */
|
SEL_POLICY, /* allow userspace to read the in kernel policy */
|
||||||
SEL_VALIDATE_TRANS, /* compute validatetrans decision */
|
SEL_VALIDATE_TRANS, /* compute validatetrans decision */
|
||||||
|
SEL_ENFORCE_START, /* compute validatetrans decision */
|
||||||
SEL_INO_NEXT, /* The next inode number to use */
|
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,
|
.write = sel_write_enforce,
|
||||||
.llseek = generic_file_llseek,
|
.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,
|
static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
|
||||||
size_t count, loff_t *ppos)
|
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_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
|
||||||
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
|
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
|
||||||
S_IWUGO},
|
S_IWUGO},
|
||||||
|
[SEL_ENFORCE_START] = {"enforce_start", &sel_enforce_start_ops,
|
||||||
|
S_IRUGO|S_IWUSR},
|
||||||
/* last one */ {""}
|
/* last one */ {""}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user