精华内容
下载资源
问答
  • stk3x1x driver分析 1:注册驱动 定义 i2c_driver static struct i2c_driver stk_ps_driver = { .driver = { .name = DEVICE_NAME, .owner = THIS_MODULE, .of_match_table = stk_match_table, /*使...

    stk3x1x driver分析

    1:注册驱动

    定义 i2c_driver

    static struct i2c_driver stk_ps_driver =
    {
        .driver = {
            .name = DEVICE_NAME,
    		.owner = THIS_MODULE,
    		.of_match_table = stk_match_table, /*使用设备树信息匹配*/
        },
        .probe = stk3x1x_probe,  /*定义 probe 入口*/
        .remove = stk3x1x_remove,
        .id_table = stk_ps_id,
    };
    

    定义 of_device_id

    static struct of_device_id stk_match_table[] = {
    	{ .compatible = "stk,stk3x1x", }, /*使用 "stk,stk3x1x" 来与设备树信息做匹配*/
    	{ },
    };
    

    module_init&add_driver

    static int __init stk3x1x_init(void)
    {
    	int ret;
        ret = i2c_add_driver(&stk_ps_driver);  /*添加一个 I2c driver设备  可参考 I2c驱动框架 */
        if (ret)
            return ret;
    
        return 0;
    }
    module_init(stk3x1x_init);
    

    I2c驱动框架 1.

    设备树信息定义

    这里只添加stk这个sensor的设备树device信息关于高通平台的I2c设备树配置可参考 高通平台 I2c设备配置简要 2.

    stk@48 {
      compatible = "stk,stk3x1x";
      reg = <0x48>;
      interrupt-parent = <&msm_gpio>;  /*指明其 父中断控制器  详情可参考 设备树中配置中断信息*/
      interrupts = <94 0x2>;          /*指明中断号  详情可参考 设备树中配置中断号*/
      vdd-supply = <&pm8909_l17>;    /* 申请 一路电 name 为vdd*/
      vio-supply = <&pm8909_l6>;     /* 申请 一路电 name 为vio, 可参考 高通平台ldo电的使用*/ 
      stk,irq-gpio = <&msm_gpio 94 0x02>; /* 中断gpio*/
      stk,transmittance = <500>;
      stk,state-reg = <0x00>;
      stk,psctrl-reg = <0x71>;
      stk,alsctrl-reg = <0x38>;
      stk,ledctrl-reg = <0xFF>;
      stk,wait-reg = <0x07>;
      stk,ps-thdh = <1700>;
      stk,ps-thdl = <1500>;
      stk,use-fir;             /* 这些 sensor寄存器相关的信息会在driver驱动中 获取并使用*/
     };
    

    设备树中配置中断信息 3.

    设备树中配置中断号 4.

    高通平台ldo电的使用 5.

    2:driver porbe流程

    这里简介 diver_probe函数的过程,具体platform device driver如何匹配,及I2c设备匹配流程 可参考 I2c驱动框架 1. platform device driver匹配流程 6.

    定义 stk3x1x 结构数据 struct stk3x1x_data

    struct stk3x1x_data *ps_data = kzalloc(sizeof(struct stk3x1x_data),GFP_KERNEL);
    这里简列 stk3x1x_data中较为重要 成员

    struct stk3x1x_data {
    	struct i2c_client *client;             /* 记录设备 I2c client*/
    	struct stk3x1x_platform_data *pdata;   /* 记录私有数据*/
    	struct sensors_classdev als_cdev;      /* */
    	struct sensors_classdev ps_cdev;       /* */ 
        int32_t irq;
        struct work_struct stk_work;
    	struct workqueue_struct *stk_wq;
    	int32_t ps_distance_last;
    	bool ps_enabled;
    	struct wake_lock ps_wakelock;
    	struct work_struct stk_ps_work;
    	struct workqueue_struct *stk_ps_wq;
    	struct input_dev *als_input_dev;
    	bool als_enabled;
    	struct hrtimer als_timer;
    	struct hrtimer ps_timer;
    	struct regulator *vdd;
    	struct regulator *vio;
    };
    

    定义平stk3x1x 的私有数据 struct stk3x1x_platform_data

    struct stk3x1x_platform_data *plat_data = devm_kzalloc(&client->dev,sizeof(struct stk3x1x_platform_data), GFP_KERNEL);
    /* 申请 设备数据 结构内存空间, 这里是用devm_kzalloc, 需要填充device 的设备结构, 当设备被卸载时, 该内存自动会被释放掉。*/
    这里简列 stk3x1x_platform_data 中的成员变量

    struct stk3x1x_platform_data {
    	uint8_t state_reg;
    	uint8_t psctrl_reg;
    	uint8_t alsctrl_reg;
    	uint8_t ledctrl_reg;
    	uint8_t wait_reg;
    	uint16_t ps_thd_h;
    	uint16_t ps_thd_l;
    	int int_pin;
    	uint32_t transmittance;
    	uint32_t int_flags;
    	bool use_fir;
    };
    
    ps_data->client = client; /* 记录设备 I2c client*/
    i2c_set_clientdata(client,ps_data); /*设置 device的 私有数据,  就是把  该driver  我们封装的数据, 填充到 device的 private数据中, 使用 driver_data 建立好 链接*/
                                        /*具体实现:
                                        i2c_client->dev->device_private->driver_data  =  sensor (void *) data
                                        */
    mutex_init(&ps_data->io_lock);  /*初始化 一个 互斥锁io_lock , 具体可参考  互斥锁的简单使用*/
    wake_lock_init(&ps_data->ps_wakelock,WAKE_LOCK_SUSPEND, "stk_input_wakelock");  /*初始化 一个 锁wake_lock , 具体可参考 wake_lock的简单使用*/
    
    
    

    互斥锁的简单使用 7.

    wake_lock的简单使用 8.

    解析设备树信息 并填充私有数据

    if (client->dev.of_node) {
    	stk3x1x_parse_dt(&client->dev, plat_data);
    	    --->  static int stk3x1x_parse_dt(struct device *dev,struct stk3x1x_platform_data *pdata)
                    {
                    	struct device_node *np = dev->of_node;
                    	u32 temp_val;
                    	pdata->int_pin = of_get_named_gpio_flags(np, "stk,irq-gpio",0, &pdata->int_flags);
                    	rc = of_property_read_u32(np, "stk,transmittance", &temp_val);
                    	pdata->transmittance = temp_val;
                    	rc = of_property_read_u32(np, "stk,state-reg", &temp_val);
                    	pdata->state_reg = temp_val;
                    	rc = of_property_read_u32(np, "stk,psctrl-reg", &temp_val);
                    	pdata->psctrl_reg = (u8)temp_val;
                    	rc = of_property_read_u32(np, "stk,alsctrl-reg", &temp_val);
                    	pdata->alsctrl_reg = (u8)temp_val;
                    	rc = of_property_read_u32(np, "stk,ledctrl-reg", &temp_val);
                    	if (!rc)
                    	pdata->ledctrl_reg = (u8)temp_val;
                    	rc = of_property_read_u32(np, "stk,wait-reg", &temp_val);
                    	pdata->wait_reg = (u8)temp_val;
                    	rc = of_property_read_u32(np, "stk,ps-thdh", &temp_val);
                    	pdata->ps_thd_h = (u16)temp_val;
                    	rc = of_property_read_u32(np, "stk,ps-thdl", &temp_val);
                    	pdata->ps_thd_l = (u16)temp_val;
                    	pdata->use_fir = of_property_read_bool(np, "stk,use-fir");return 0;
                    }
             --->
    } else
    	plat_data = client->dev.platform_data;
    

    做init工作并填充stk3x1x 结构数据

    将需要的私有数据传递过来

    	ps_data->als_transmittance = plat_data->transmittance;
    	ps_data->int_pin = plat_data->int_pin;
    	ps_data->use_fir = plat_data->use_fir;
    	ps_data->pdata = plat_data;
    

    填充name

    	ps_data->als_input_dev->name = ALS_NAME; /*stk3x1x-ls*/
    	ps_data->ps_input_dev->name = PS_NAME;   /*proximity*/
    

    申请注册输入设备

    ps_data->als_input_dev = devm_input_allocate_device(&client->dev); /*申请 一个input device 并记录填充给 stk3x1x 结构数据中的 光感设备als_input_dev*/
    ps_data->ps_input_dev = devm_input_allocate_device(&client->dev);  /*申请 一个input device 并记录填充给 stk3x1x 结构数据中的 距感设备ps_input_dev*/
    ps_data->als_input_dev->name = ALS_NAME;
    ps_data->ps_input_dev->name = PS_NAME;
    set_bit(EV_ABS, ps_data->als_input_dev->evbit);
    set_bit(EV_ABS, ps_data->ps_input_dev->evbit);
    input_set_abs_params(ps_data->als_input_dev, ABS_MISC, 0, stk_alscode2lux(ps_data, (1<<16)-1), 0, 0);
    input_set_abs_params(ps_data->ps_input_dev, ABS_DISTANCE, 0,1, 0, 0);
    err = input_register_device(ps_data->als_input_dev);  /* 可参考linux输入子系统相关 */
    err = input_register_device(ps_data->ps_input_dev);
    input_set_drvdata(ps_data->als_input_dev, ps_data);   /* 将ps_data 填充到 ps_data->als_input_dev的相关 指针上,做链接*/
    input_set_drvdata(ps_data->ps_input_dev, ps_data);    /* 将ps_data 填充到 ps_input_dev的相关 指针上,做链接*/
    

    linux输入子系统 9.

    创建文件节点

    sysfs_create_group(&ps_data->als_input_dev->dev.kobj, &stk_als_attribute_group); /* 可参考文件节点创建相关相关 */
    sysfs_create_group(&ps_data->ps_input_dev->dev.kobj, &stk_ps_attribute_group); 
    

    文件节点创建 10.

    创建工作队列及高精度延时定时器

    ps_data->stk_ps_wq = create_singlethread_workqueue("stk_ps_wq"); /* 可参考 工作队列的使用相关 workqueue*/
    INIT_WORK(&ps_data->stk_ps_work, stk_ps_work_func);              /* INIT_WORK, 绑定处理函数*/
    hrtimer_init(&ps_data->ps_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);    /*可参考hrtimer的使用相关*/
    ps_data->ps_poll_delay = ns_to_ktime(110 * NSEC_PER_MSEC);
    ps_data->ps_timer.function = stk_ps_timer_func;                   /*制定 timer相关的 处理函数*/
    ps_data->stk_wq = create_singlethread_workqueue("stk_wq");        /*同上*/
    INIT_WORK(&ps_data->stk_work, stk_work_func);
    

    工作队列的使用 11.

    hrtimer的使用 12.

    设置相关中断

     stk3x1x_setup_irq(client);
        --->struct stk3x1x_data *ps_data = i2c_get_clientdata(client);
            irq = gpio_to_irq(ps_data->int_pin);  /*获取 中断gpio对应的中断号*/
            ps_data->irq = irq;                   /*记录到设备数据中去*/
        	err = gpio_request(ps_data->int_pin,"stk-int");    /*request gpio*/
        	err = gpio_direction_input(ps_data->int_pin);
            #if ((STK_INT_PS_MODE == 0x03) || (STK_INT_PS_MODE	== 0x02))
            	err = request_any_context_irq(irq, stk_oss_irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, DEVICE_NAME, ps_data); /*申请一个中断*/
            #else
            	err = request_any_context_irq(irq, stk_oss_irq_handler, IRQF_TRIGGER_LOW, DEVICE_NAME, ps_data);    /*可参考 中断irq申请使用相关*/
        	disable_irq(irq);
        	return 0;--->
    

    中断irq的使用 13.

    初始化电相关及上电操作

    stk3x1x_power_init(ps_data, true);
        --->if (!on) {
        		if (regulator_count_voltages(data->vdd) > 0)
        		regulator_set_voltage(data->vdd,0, STK3X1X_VDD_MAX_UV);
        		regulator_put(data->vdd);
        		if (regulator_count_voltages(data->vio) > 0)
        		regulator_set_voltage(data->vio,0, STK3X1X_VIO_MAX_UV);
        		regulator_put(data->vio);
            } 
            else {
        		data->vdd = regulator_get(&data->client->dev, "vdd"); /* 获取电 ,会根据设备树中“vdd-supply“  "vdd"会被加上 -supply string 解析*/
            		if (regulator_count_voltages(data->vdd) > 0) {
            			ret = regulator_set_voltage(data->vdd,STK3X1X_VDD_MIN_UV,STK3X1X_VDD_MAX_UV);    /*设置电,可参考高通使用ldo电相关*/
            		}
            	data->vio = regulator_get(&data->client->dev, "vio");
            		if (regulator_count_voltages(data->vio) > 0) {
            			ret = regulator_set_voltage(data->vio,STK3X1X_VIO_MIN_UV,STK3X1X_VIO_MAX_UV);
            		}
            	}
            return 0;--->
    stk3x1x_power_ctl(ps_data, true);
        --->
        {
            if (!on && data->power_enabled) {
    		ret = regulator_disable(data->vdd);
    		ret = regulator_disable(data->vio);
    		data->power_enabled = on;
    	    }
    	    else if (on && !data->power_enabled) {
        		ret = regulator_enable(data->vdd);
        		ret = regulator_enable(data->vio);
        		data->power_enabled = on;
        	}
        	return ret;
        }
        --->
    ps_data->als_enabled = false;
    ps_data->ps_enabled = false;
    

    高通ldo的使用 14.

    注册sensor,指明使能sensor的函数指针

    ps_data->als_cdev = sensors_light_cdev;
    ps_data->als_cdev.sensors_enable = stk_als_enable_set; /*传入设置使能sensor的函数指针*/
    ps_data->als_cdev.sensors_poll_delay = stk_als_poll_delay_set;
    err = sensors_classdev_register(&ps_data->als_input_dev->dev,
    		&ps_data->als_cdev);
    ps_data->ps_cdev = sensors_proximity_cdev;
    ps_data->ps_cdev.sensors_enable = stk_ps_enable_set;    /*传入设置使能sensor的函数指针*/
    err = sensors_classdev_register(&ps_data->ps_input_dev->dev,
    		&ps_data->ps_cdev);
    err = stk3x1x_power_ctl(ps_data, false);/* enable device power only when it is enabled */
    return 0;
    

    使能的过程

    ```cpp
    static int stk_als_enable_set(struct sensors_classdev *sensors_cdev,
    						unsigned int enabled)
    {
    	struct stk3x1x_data *als_data = container_of(sensors_cdev,struct stk3x1x_data, als_cdev);
    	mutex_lock(&als_data->io_lock);
    	err = stk3x1x_enable_als(als_data, enabled);
    	mutex_unlock(&als_data->io_lock);
    	return 0;
    }
    
    static int32_t stk3x1x_enable_als(struct stk3x1x_data *ps_data, uint8_t enable)
    {
        int32_t ret;
    	uint8_t w_state_reg;
    	uint8_t curr_als_enable = (ps_data->als_enabled)?1:0;
    	if(curr_als_enable == enable)   /* 判断是否已经使能了*/
    		return 0;
    	if (enable) {
    		ret = stk3x1x_device_ctl(ps_data, enable);
    		if (ret)
    			return ret;
    	}
    #ifndef STK_POLL_ALS
        if (enable)
    	{
            stk3x1x_set_als_thd_h(ps_data, 0x0000);
            stk3x1x_set_als_thd_l(ps_data, 0xFFFF);
    	}
    #endif
        ret = i2c_smbus_read_byte_data(ps_data->client, STK_STATE_REG);
    	w_state_reg = (uint8_t)(ret & (~(STK_STATE_EN_ALS_MASK | STK_STATE_EN_WAIT_MASK)));
    	if(enable)
    		w_state_reg |= STK_STATE_EN_ALS_MASK;
    	else if (ps_data->ps_enabled)
    		w_state_reg |= STK_STATE_EN_WAIT_MASK;
        ret = i2c_smbus_write_byte_data(ps_data->client, STK_STATE_REG, w_state_reg);
        if (enable)
        {
    		ps_data->als_enabled = true;
    		hrtimer_start(&ps_data->als_timer, ps_data->als_poll_delay, HRTIMER_MODE_REL);/*开启hrtimer  看后面的 timer处理函数*/
    		enable_irq(ps_data->irq);
        }
    	else
    	{
    		ps_data->als_enabled = false;
    		hrtimer_cancel(&ps_data->als_timer);
    		if(!(ps_data->ps_enabled))
    		disable_irq(ps_data->irq);
    	}
    	if (!enable) {
    		ret = stk3x1x_device_ctl(ps_data, enable);
    		if (ret)
    		return ret;
    	}
        return ret;
    }
    
    static int stk3x1x_device_ctl(struct stk3x1x_data *ps_data, bool enable)
    {
    	int ret;
    	struct device *dev = &ps_data->client->dev;
    	if (enable && !ps_data->power_enabled) {
    		ret = stk3x1x_power_ctl(ps_data, true);
    		ret = stk3x1x_init_all_setting(ps_data->client, ps_data->pdata); 
    		      --->
    		          {
    		            ret = stk3x1x_software_reset(ps_data);
                    	stk3x1x_check_pid(ps_data);
                    	ret = stk3x1x_init_all_reg(ps_data, plat_data);
                    	stk_init_code_threshold_table(ps_data);
                    	if (plat_data->use_fir)
    		            stk3x1x_init_fir(ps_data);
    		          }
    		      --->
    	} 
    	else if (!enable && ps_data->power_enabled) {
    		if (!ps_data->als_enabled && !ps_data->ps_enabled) {
    			ret = stk3x1x_power_ctl(ps_data, false);
    		} 
    	} 
    	return 0;eturn ret;
    }
    

    hrtimer处理函数

    static enum hrtimer_restart stk_als_timer_func(struct hrtimer *timer)
    {
    	struct stk3x1x_data *ps_data = container_of(timer, struct stk3x1x_data, als_timer);
    	queue_work(ps_data->stk_als_wq, &ps_data->stk_als_work); /* 轮训的方式 是每隔一段时间这样调用 一下 这个工作*/
    	hrtimer_forward_now(&ps_data->als_timer, ps_data->als_poll_delay);
    	return HRTIMER_RESTART;
    }
    static void stk_als_work_func(struct work_struct *work)
    {   /*获取信息上报*/
    	struct stk3x1x_data *ps_data = container_of(work, struct stk3x1x_data, stk_als_work);
    	int32_t reading;
        mutex_lock(&ps_data->io_lock);
    	reading = stk3x1x_get_als_reading(ps_data);
    	if(reading < 0)
    		return;
    	ps_data->als_lux_last = stk_alscode2lux(ps_data, reading);
    	input_report_abs(ps_data->als_input_dev, ABS_MISC, ps_data->als_lux_last);
    	input_sync(ps_data->als_input_dev);
    	mutex_unlock(&ps_data->io_lock);
    }
    

    中断处理方式

    static irqreturn_t stk_oss_irq_handler(int irq, void *data)
    {
    	struct stk3x1x_data *pData = data;
    	disable_irq_nosync(irq);
    	queue_work(pData->stk_wq,&pData->stk_work); /*调度 stk_wq*/
    	return IRQ_HANDLED;
    }
    

    stk_wq

    static void stk_work_func(struct work_struct *work)
    {
    	uint32_t reading;
    #if ((STK_INT_PS_MODE != 0x03) && (STK_INT_PS_MODE != 0x02))
        int32_t ret;
        uint8_t disable_flag = 0;
        uint8_t org_flag_reg;
    #endif	/* #if ((STK_INT_PS_MODE != 0x03) && (STK_INT_PS_MODE != 0x02)) */
    #ifndef CONFIG_STK_PS_ALS_USE_CHANGE_THRESHOLD
    	uint32_t nLuxIndex;
    #endif
    	struct stk3x1x_data *ps_data = container_of(work, struct stk3x1x_data, stk_work);
    	int32_t near_far_state;
        mutex_lock(&ps_data->io_lock);
    #if (STK_INT_PS_MODE	== 0x03)
    	near_far_state = gpio_get_value(ps_data->int_pin);
    #elif	(STK_INT_PS_MODE	== 0x02)
    	near_far_state = !(gpio_get_value(ps_data->int_pin));
    #endif
    #if ((STK_INT_PS_MODE == 0x03) || (STK_INT_PS_MODE	== 0x02))
    	ps_data->ps_distance_last = near_far_state;
    	input_report_abs(ps_data->ps_input_dev, ABS_DISTANCE, near_far_state);
    	input_sync(ps_data->ps_input_dev);
    	wake_lock_timeout(&ps_data->ps_wakelock, 3*HZ);
    	reading = stk3x1x_get_ps_reading(ps_data);
    #else
    	/* mode 0x01 or 0x04 */
    	org_flag_reg = stk3x1x_get_flag(ps_data);
        if (org_flag_reg & STK_FLG_ALSINT_MASK)
        {
    		disable_flag |= STK_FLG_ALSINT_MASK;
            reading = stk3x1x_get_als_reading(ps_data);
    #ifndef CONFIG_STK_PS_ALS_USE_CHANGE_THRESHOLD
            nLuxIndex = stk_get_lux_interval_index(reading);
            stk3x1x_set_als_thd_h(ps_data, code_threshold_table[nLuxIndex]);
            stk3x1x_set_als_thd_l(ps_data, code_threshold_table[nLuxIndex-1]);
    #else
            stk_als_set_new_thd(ps_data, reading);
    #endif //CONFIG_STK_PS_ALS_USE_CHANGE_THRESHOLD
    		ps_data->als_lux_last = stk_alscode2lux(ps_data, reading);
    		input_report_abs(ps_data->als_input_dev, ABS_MISC, ps_data->als_lux_last);
    		input_sync(ps_data->als_input_dev);
        }
        if (org_flag_reg & STK_FLG_PSINT_MASK)
        {
    		disable_flag |= STK_FLG_PSINT_MASK;
    		near_far_state = (org_flag_reg & STK_FLG_NF_MASK)?1:0;
    
    		ps_data->ps_distance_last = near_far_state;
    		input_report_abs(ps_data->ps_input_dev, ABS_DISTANCE, near_far_state);
    		input_sync(ps_data->ps_input_dev);
    		wake_lock_timeout(&ps_data->ps_wakelock, 3*HZ);
            reading = stk3x1x_get_ps_reading(ps_data);
        }
        ret = stk3x1x_set_flag(ps_data, org_flag_reg, disable_flag);
    #endif
    
    	msleep(1);
        enable_irq(ps_data->irq);
        mutex_unlock(&ps_data->io_lock);
    	return;
    }
    #endif
    

    1. 待添加 I2c驱动框架 ↩︎ ↩︎

    2. 待添加 高通平台 I2c设备配置简要 ↩︎

    3. 待添加 设备树中配置中断信息 ↩︎

    4. 待添加 设备树中配置中断号 ↩︎

    5. 待添加 高通平台ldo电的使用 ↩︎

    6. 待添加 platform device driver匹配流程 ↩︎

    7. 待添加 互斥锁的简单使用 ↩︎

    8. 待添加 wake_lock的简单使用 ↩︎

    9. 待添加 linux输入子系统 ↩︎

    10. 待添加 文件节点创建 ↩︎

    11. 待添加 工作队列的使用 ↩︎

    12. 待添加 hrtimer的使用 ↩︎

    13. 待添加 中断irq的使用 ↩︎

    14. 待添加 高通ldo的使用 ↩︎

    展开全文
  • Rust ADS1x1x超小型,低功耗模数转换器(ADC)驱动器 这是一个ADS1013平台无关锈病司机,ADS1014,ADS1015,ADS1113,ADS1114和ADS1115超小型,低功耗模拟-数字转换器(ADC)的基础上, 的特点。 此驱动程序使您...
  • ThinkpadX1Carbon笔记本电脑NFC驱动是一款非常好用的笔记本驱动程序,它能有效读取连接电脑各设备资源信息,读取快读确保数据不丢失。快下载体验吧!软件介绍说到NFC(NearFieldCommunication,近距离无线通讯技术,...
  • mBot机器人是一款由创客工场(Makeblock) 推出的金属机器人积木套装,该套装将Scratch图形化编程工具与机器人金属积木结合到一起,可以使用mBlock 设计程序,驱动与Arduino 电路板兼容的传感器,从而灵活控制mBot...
  • "ATI Mobility Radeon HD 4500 Series" = ati2mtag_M9x, PCI\VEN_1002&DEV;_9553 "ATI Mobility Radeon HD 4650" = ati2mtag_M9x, PCI\VEN_1002&DEV;_9480 "ATI Mobility Radeon HD 4670" = ati2mtag_M9x, PCI\VEN_...
  • hackintosh-x1c-4th-OC 当前硬件配置信息: 型号 ThinkPad x1c 4th 系统 macOS 11.2 \ Win10 ...注意:驱动4k屏幕需要解锁bios,并设置DVMT为64MB或者64MB以上如果没有设置DVMT的话,最高支持2k屏幕
  • 说到NFC(Near Field Communication,近距离无线通讯技术,也称近场... 比如Thinkpad X1 Carbon、S1 Yoga等笔记本就内置了此模块,联想的某些服务则可以利用此模块(比如QuickControl)。日前联想官网发布了Thinkpad
  • 驱动与伺服定位概述

    2021-01-20 00:07:02
     以环球公司用FLEXJET头的单横梁贴片机GSM1为例,包括X、y、z、角度Theta、板宽控制PWC、皮带传输Belt Transfer六个轴,共同组成驱动系统。其中X、y轴是高电源轴,受高电源箱中的对应伺服放人器控制;角度Theta、板...
  • 最主要的问题的是x1e的显卡驱动问题,没有GTX 1050 TI的适配驱动,导致无法进入图形化界面; 1.插入安装盘,进入BIOS,设置U盘启动 2. 进入安装选项,光标在第一个“try …Ubuntu”,按e键进入命令行,在linux内核...

    最主要的问题的是x1e的显卡驱动问题,没有GTX 1050 TI的适配驱动,导致无法进入图形化界面;
    1.插入安装盘,进入BIOS,设置U盘启动
    2. 进入安装选项,光标在第一个“try …Ubuntu”,按e键进入命令行,在linux内核配置那一行的末尾加上:nouveau.modeset=0 acpi=off,按ctrl+x进入
    3. 点击install图标进入安装配置,完成分区,密码等设置,完成安装
    4. 重启,进入grub选择界面,再次按e进入命令行,在linux内核配置那一行的末尾加上:nouveau.modeset=0 acpi=off,按ctrl+x进入
    5. 因为现在的系统缺失nvidia的驱动,需要手动安装:
    执行命令来检测nVidia显卡型号和推荐的驱动程序的模型

    ubuntu-drivers devices
    

    执行自动化安装命令来自动安装推荐的驱动

    ubuntu-drivers autoinstall
    

    即可完成Ubuntu 18.04的安装

    展开全文
  • 单片机驱动TFT液晶原理图, void address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) { main_W_com_data(0x0020,x1);//设置X坐标位置 main_W_com_data(0x0021,y1);//设置Y坐标位置 ...

空空如也

空空如也

1 2 3 4 5
收藏数 99
精华内容 39
关键字:

x1驱动x