sp

USE [MES_DS_MCD]
GO
/****** Object:  StoredProcedure [SSRS].[MataAnodes_p]    Script Date: 2014/8/5 10:39:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [SSRS].[MataAnodes_p] 
    -- Add the parameters for the stored procedure here 
 
    @MaterialUA varchar(30) = NULL, 
       @Operation varchar(30) = NULL, 
    @PN varchar(50) = NULL,   
    @DateFrom varchar(50) = NULL, 
    @DateTo varchar(50) = NULL,
    @OracleOrgCode varchar(30) = NULL,
    @LogicalPlant varchar(30) = NULL  
AS 
    SET NOCOUNT ON; 
    Declare @mat varchar(20) 
    Declare @date varchar(20) 
   --if @MaterialUA='Material' 
   --     set @mat= ' AND ( part_type Like '''+@PN +''''   +' or partnum Like '''+@PN +''''   +' ) ' 
   -- else 
   --     if  @MaterialUA='UA'
   --         set @mat= ' AND uano Like '''+@PN +'%''' 
    
    
    -- if @Operation='Prensas' 
    --    set @date=  ' where  CAST(OMASTERDATE AS DATE) between ''' + @DateFrom + '''  And  '''+ @DateTo + ' '' ' 
    --else 
    --    if  @Operation='Sin'
    --        set @date=  ' where  CAST(fin_date AS DATE) between ''' + @DateFrom + '''  And  '''+ @DateTo + ' '' ' 
           
           
         
Declare @sql varchar(max)='SELECT * from APPS.MATA_ANODES  '
   
  
 
        --Set @sql = @sql +  @date
    if @Operation='Prensas' 
   Set @sql  = @sql + ' where  CAST(OMASTERDATE AS DATE) between ''' + @DateFrom + '''  And  '''+ @DateTo + ' '' ' 
  else 
        if  @Operation='Sin'
     Set @sql  = @sql + ' where  CAST(fin_date AS DATE) between ''' + @DateFrom + '''  And  '''+ @DateTo + ' '' '
    
      
      
       if @MaterialUA='Material' 
       set @sql  = @sql +   ' AND ( part_type Like '''+@PN +'%'''   +' or partnum Like '''+@PN +'%'''   +' ) '
      
       else 
    if  @MaterialUA='UA'
    set @sql  = @sql +  ' AND uano Like '''+@PN +'%''' 
        --Set @sql = @sql + @mat
         

    exec (@sql) 
    return

内容概要:文章以“智能网页数据标注工具”为例,深入探讨了谷歌浏览器扩展在毕业设计中的实战应用。通过开发具备实体识别、情感分类等功能的浏览器扩展,学生能够融合前端开发、自然语言处理(NLP)、本地存储与模型推理等技术,实现高效的网页数据标注系统。文中详细解析了扩展的技术架构,涵盖Manifest V3配置、内容脚本与Service Worker协作、TensorFlow.js模型在浏览器端的轻量化部署与推理流程,并提供了核心代码实现,包括文本选择、标注工具栏动态生成、高亮显示及模型预测功能。同时展望了多模态标注、主动学习与边缘计算协同等未来发展方向。; 适合人群:具备前端开发基础、熟悉JavaScript和浏览器机制,有一定AI模型应用经验的计算机相关专业本科生或研究生,尤其适合将浏览器扩展与人工智能结合进行毕业设计的学生。; 使用场景及目标:①掌握浏览器扩展开发全流程,理解内容脚本、Service Worker与弹出页的通信机制;②实现在浏览器端运行轻量级AI模型(如NER、情感分析)的技术方案;③构建可用于真实场景的数据标注工具,提升标注效率并探索主动学习、协同标注等智能化功能。; 阅读建议:建议结合代码实例搭建开发环境,逐步实现标注功能并集成本地模型推理。重点关注模型轻量化、内存管理与DOM操作的稳定性,在实践中理解浏览器扩展的安全机制与性能优化策略。
基于Gin+GORM+Casbin+Vue.js的权限管理系统是一个采用前后端分离架构的企业级权限管理解决方案,专为软件工程和计算机科学专业的毕业设计项目开发。该系统基于Go语言构建后端服务,结合Vue.js前端框架,实现了完整的权限控制和管理功能,适用于各类需要精细化权限管理的应用场景。 系统后端采用Gin作为Web框架,提供高性能的HTTP服务;使用GORM作为ORM框架,简化数据库操作;集成Casbin实现灵活的权限控制模型。前端基于vue-element-admin模板开发,提供现代化的用户界面和交互体验。系统采用分层架构和模块化设计,确保代码的可维护性和可扩展性。 主要功能包括用户管理、角色管理、权限管理、菜单管理、操作日志等核心模块。用户管理模块支持用户信息的增删改查和状态管理;角色管理模块允许定义不同角色并分配相应权限;权限管理模块基于Casbin实现细粒度的访问控制;菜单管理模块动态生成前端导航菜单;操作日志模块记录系统关键操作,便于审计和追踪。 技术栈方面,后端使用Go语言开发,结合Gin、GORM、Casbin等成熟框架;前端使用Vue.js、Element UI等现代前端技术;数据库支持MySQL、PostgreSQL等主流关系型数据库;采用RESTful API设计规范,确保前后端通信的标准化。系统还应用了单例模式、工厂模式、依赖注入等设计模式,提升代码质量和可测试性。 该权限管理系统适用于企业管理系统、内部办公平台、多租户SaaS应用等需要复杂权限控制的场景。作为毕业设计项目,它提供了完整的源码和论文文档,帮助学生深入理解前后端分离架构、权限控制原理、现代Web开发技术等关键知识点。系统设计规范,代码结构清晰,注释完整,非常适合作为计算机相关专业的毕业设计参考或实际项目开发的基础框架。 资源包含完整的系统源码、数据库设计文档、部署说明和毕
/* * sp0821.c sp0821 yuv module * * Author: Bruce <sunchengwei@longcheer.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/irq.h> #include <linux/firmware.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/gameport.h> #include <linux/moduleparam.h> #include <linux/mutex.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/ktime.h> #include <linux/kthread.h> #include <linux/regulator/consumer.h> #include "sp_sp0821_yuv.h" #include "../../../aw37004/aw37004.h" #include <soc/oplus/system/oplus_project.h> #include <linux/videodev2.h> #include <linux/cdev.h> #include <linux/atomic.h> #include <linux/types.h> extern void ISP_MCLK3_EN (bool En); extern int aw37004_camera_power_up(int out_iotype, unsigned int out_val); #define kal_uint16 unsigned short #define kal_uint32 unsigned int /***************************************************************** * sp0821 marco ******************************************************************/ #define SP0821_DRIVER_VERSION "V2.0" #define SP0821_PRODUCT_NUM 4 #define SP0821_PRODUCT_NAME_LEN 8 #define SP0821_SENSOR_ID 0x3a6c #define SP0821_MCLK_ON "sp0821_mclk_on" #define SP0821_MCLK_OFF "sp0821_mclk_off" /***************************************************************** * sp0821 global global variable ******************************************************************/ static unsigned char read_reg_id = 0; static unsigned char read_reg_value = 0; static int read_reg_flag = 0; static int driver_flag = 0; struct sp0821 *g_sp0821 = NULL; /********************************************************** * i2c write and read **********************************************************/ static void sp0821_i2c_write(struct sp0821 *sp0821, int address, int data) { u8 i2c_buf[8]; struct i2c_client *client = sp0821->i2c_client; struct i2c_msg msg[1]; msg[0].flags = !I2C_M_RD; msg[0].addr = client->addr; msg[0].len = 3; msg[0].buf = i2c_buf; i2c_buf[0] = (address & 0xff00)>>8; i2c_buf[1] = (address & 0xff); i2c_buf[2] = data; i2c_transfer(client->adapter, msg, 1); //printk("write sp0821 addr: 0x%4X val:0x%4X\n", address, data); } static unsigned char sp0821_i2c_read(struct sp0821 *sp0821, int address) { unsigned char rxdata = 0x00; unsigned char i2c_buf[4]; int ret = 0; int retry = 2; u8 i2c_addr[2]; struct i2c_client *client = sp0821->i2c_client; struct i2c_msg msgs[2]; i2c_addr[0] = (address & 0xff00)>>8; i2c_addr[1] = (address & 0xff); msgs[0].flags = 0; msgs[0].addr = (client->addr); msgs[0].len = 2; msgs[0].buf = i2c_addr; msgs[1].flags = I2C_M_RD; msgs[1].addr = (client->addr); msgs[1].len = 1; msgs[1].buf = i2c_buf; while (retry > 0) { ret = i2c_transfer(client->adapter, msgs, 2); //qvga_dev_err(&client->dev, "%s: read step1 ret:%d msgs[1].addr=%x\n", __func__, ret, msgs[1].addr); if (retry >0) { mdelay(20); if (ret == 0) { return 0; } } retry--; mdelay(2); } rxdata = i2c_buf[0]; return rxdata; } static struct sp0821 *sp0821_malloc_init(struct i2c_client *client) { struct sp0821 *sp0821 = devm_kzalloc(&client->dev, sizeof(struct sp0821), GFP_KERNEL); if (sp0821 == NULL) { qvga_dev_err(&client->dev, "%s: devm_kzalloc failed.\n", __func__); return NULL; } sp0821->i2c_client = client; pr_info("%s enter , client_addr = 0x%02x\n", __func__, sp0821->i2c_client->addr); return sp0821; } #if 1 void sp0821_Init(struct sp0821 *sp0821) { /*SYS MCLK=24MHZ*/ sp0821_i2c_write(sp0821, 0x0103,0x01); sp0821_i2c_write(sp0821, 0x0100,0x00); sp0821_i2c_write(sp0821, 0x309b,0xf0); sp0821_i2c_write(sp0821, 0x30b0,0x0a); sp0821_i2c_write(sp0821, 0x30b8,0x21); sp0821_i2c_write(sp0821, 0x320c,0x01); sp0821_i2c_write(sp0821, 0x320d,0x6a); sp0821_i2c_write(sp0821, 0x320e,0x01); sp0821_i2c_write(sp0821, 0x320f,0xba); sp0821_i2c_write(sp0821, 0x3301,0x04); sp0821_i2c_write(sp0821, 0x3304,0x0c); sp0821_i2c_write(sp0821, 0x3305,0x00); sp0821_i2c_write(sp0821, 0x3306,0x10); sp0821_i2c_write(sp0821, 0x3307,0x02); sp0821_i2c_write(sp0821, 0x3308,0x04); sp0821_i2c_write(sp0821, 0x330a,0x00); sp0821_i2c_write(sp0821, 0x330b,0x30); sp0821_i2c_write(sp0821, 0x330e,0x01); sp0821_i2c_write(sp0821, 0x330f,0x01); sp0821_i2c_write(sp0821, 0x3310,0x01); sp0821_i2c_write(sp0821, 0x331e,0x09); sp0821_i2c_write(sp0821, 0x3333,0x10); sp0821_i2c_write(sp0821, 0x3334,0x40); sp0821_i2c_write(sp0821, 0x334c,0x01); sp0821_i2c_write(sp0821, 0x33b3,0x3e); sp0821_i2c_write(sp0821, 0x349f,0x02); sp0821_i2c_write(sp0821, 0x34a6,0x01); sp0821_i2c_write(sp0821, 0x34a7,0x07); sp0821_i2c_write(sp0821, 0x34a8,0x3a); sp0821_i2c_write(sp0821, 0x34a9,0x38); sp0821_i2c_write(sp0821, 0x34e9,0x38); sp0821_i2c_write(sp0821, 0x34f8,0x07); sp0821_i2c_write(sp0821, 0x3630,0x65); sp0821_i2c_write(sp0821, 0x3637,0x47); sp0821_i2c_write(sp0821, 0x363a,0xe0); sp0821_i2c_write(sp0821, 0x3670,0x03); sp0821_i2c_write(sp0821, 0x3674,0x75); sp0821_i2c_write(sp0821, 0x3675,0x65); sp0821_i2c_write(sp0821, 0x3676,0x65); sp0821_i2c_write(sp0821, 0x367c,0x01); sp0821_i2c_write(sp0821, 0x367d,0x03); sp0821_i2c_write(sp0821, 0x3690,0xe0); sp0821_i2c_write(sp0821, 0x3691,0xe1); sp0821_i2c_write(sp0821, 0x3692,0xe1); sp0821_i2c_write(sp0821, 0x3693,0xe1); sp0821_i2c_write(sp0821, 0x3694,0x03); sp0821_i2c_write(sp0821, 0x3695,0x07); sp0821_i2c_write(sp0821, 0x3696,0x07); sp0821_i2c_write(sp0821, 0x37f9,0x29); sp0821_i2c_write(sp0821, 0x3900,0x91); sp0821_i2c_write(sp0821, 0x3904,0x0f); sp0821_i2c_write(sp0821, 0x3908,0x00); sp0821_i2c_write(sp0821, 0x391b,0x07); sp0821_i2c_write(sp0821, 0x391c,0x0a); sp0821_i2c_write(sp0821, 0x391d,0x15); sp0821_i2c_write(sp0821, 0x391e,0x28); sp0821_i2c_write(sp0821, 0x391f,0x41); sp0821_i2c_write(sp0821, 0x3948,0x00);//blc sp0821_i2c_write(sp0821, 0x4509,0x10); sp0821_i2c_write(sp0821, 0x470b,0x0a); sp0821_i2c_write(sp0821, 0x470d,0x06); sp0821_i2c_write(sp0821, 0x5000,0xc2); sp0821_i2c_write(sp0821, 0x5001,0x01); sp0821_i2c_write(sp0821, 0x5170,0x2c); sp0821_i2c_write(sp0821, 0x5172,0xc1); sp0821_i2c_write(sp0821, 0x518b,0x00);//again sp0821_i2c_write(sp0821, 0x518c,0x20); sp0821_i2c_write(sp0821, 0x518d,0x01);//shutter sp0821_i2c_write(sp0821, 0x518e,0x7c); sp0821_i2c_write(sp0821, 0x518f,0x00); sp0821_i2c_write(sp0821, 0x519e,0x10); sp0821_i2c_write(sp0821, 0x300a,0x00);//SIP input sp0821_i2c_write(sp0821, 0x0100,0x01); /*shutter gain must write after stream on */ sp0821_i2c_write(sp0821, 0x518b,0x03);//again=4x sp0821_i2c_write(sp0821, 0x518c,0x20); sp0821_i2c_write(sp0821, 0x518d,0x01);//shutter=20ms sp0821_i2c_write(sp0821, 0x518e,0xb0); sp0821_i2c_write(sp0821, 0x518f,0x00); sp0821_i2c_write(sp0821, 0x519e,0x10); } /* sensor_init */ #endif int sp0821_GetSensorID(struct sp0821 *sp0821) { int retry = 2; unsigned char reg_data = 0x00; //check if sensor ID correct do { reg_data = sp0821_i2c_read(sp0821, 0x3107)<<8|sp0821_i2c_read(sp0821, 0x3108); qvga_dev_err(sp0821->dev, "drv-%s: Read MSB Sensor ID = 0x%02x\n", __func__, reg_data); // if (reg_data == SP0821_SENSOR_ID) { if (1) { qvga_dev_err(sp0821->dev, "drv-%s: Read Sensor ID sucess = 0x%02x\n", __func__, reg_data); driver_flag = 1; return 0; } else { qvga_dev_err(sp0821->dev, "rv-%s: Read Sensor ID Fail = 0x%02x\n", __func__, reg_data); driver_flag = 0; } mdelay(10); retry--; } while (retry > 0); return -1; } static void sp0821_vcam_control(struct sp0821 *sp0821, bool flag) { // struct regulator *vcama; struct regulator *vcamio; struct regulator *vcamd; int ret; int ret1; qvga_dev_info(sp0821->dev, "%s enter\n", __func__); vcamd = regulator_get(sp0821->dev,"vcamd"); if (IS_ERR(vcamd)) { qvga_dev_err(sp0821->dev, "%s get regulator vcamd failed\n", __func__); regulator_put(vcamd); return; } else { qvga_dev_err(sp0821->dev, "%s get regulator vcamd success\n", __func__); } if (flag) { regulator_set_voltage(vcamd, 1200000, 1200000); ret = regulator_enable(vcamd); } else { regulator_disable(vcamd); } // vcama = regulator_get(sp0821->dev,"vcama"); // if (IS_ERR(vcama)) { // qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); // regulator_put(vcama); // return; // } // if (flag) { // regulator_set_voltage(vcama, 2800000, 2800000); // ret = regulator_enable(vcama); // } else { // regulator_disable(vcama); // } if (flag) { ret1 = aw37004_camera_power_up(2, 2800); if (ret1 == 0) { qvga_dev_err(sp0821->dev, "%s get regulator vcama success\n", __func__); } else { qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); } } vcamio = regulator_get(sp0821->dev,"vcamio"); if (IS_ERR(vcamio)) { qvga_dev_err(sp0821->dev, "%s get regulator vcamio failed\n", __func__); regulator_put(vcamio); return; } else { qvga_dev_err(sp0821->dev, "%s get regulator vcamio success\n", __func__); } if (flag) { regulator_set_voltage(vcamio, 1800000, 1800000); ret = regulator_enable(vcamio); } else { regulator_disable(vcamio); } return; } static void sp0821_hw_on_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 1); } } static void sp0821_hw_on_reset1(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio1)) { gpio_set_value_cansleep(sp0821->reset_gpio1, 1); } } static void sp0821_hw_off_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 0); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 1); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 0); } } static void sp0821_hw_off_reset1(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio1)) { gpio_set_value_cansleep(sp0821->reset_gpio1, 0); } } static void sp0821_hw_on(struct sp0821 *sp0821) { sp0821_hw_on_reset1(sp0821); sp0821_hw_on_reset(sp0821); sp0821_Init(sp0821); sp0821->hwen_flag = 1; } static void sp0821_hw_off(struct sp0821 *sp0821) { sp0821_hw_off_reset(sp0821); sp0821->hwen_flag = 0; } static ssize_t sp0821_get_reg(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (read_reg_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "The reg 0x%02X value is 0x%02X\n", read_reg_id, read_reg_value); read_reg_flag = 0; read_reg_id = 0; read_reg_value = 0; } else { len += snprintf(buf + len, PAGE_SIZE - len, "Please echo reg id into reg\n"); } return len; } static ssize_t sp0821_set_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { unsigned int databuf[2] = { 0 }; unsigned char reg_data = 0x00; if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { sp0821_i2c_write(g_sp0821, databuf[0], databuf[1]); } else if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 1) { reg_data = sp0821_i2c_read(g_sp0821, databuf[0]); read_reg_id = databuf[0]; read_reg_value = reg_data; read_reg_flag = 1; } return len; } static ssize_t sp0821_get_name(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (driver_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "sp_sp0821_yuv"); } else { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "none"); } return len; } static ssize_t sp0821_get_light(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; unsigned char reg_data1 = 0x00; //unsigned char reg_data2 = 0x00; u16 light = 0; reg_data1 = sp0821_i2c_read(g_sp0821, 0x5160); //reg_data2 = sp0821_i2c_read(g_sp0821, 0x516b); //light = (reg_data1<<8) + reg_data2; light = reg_data1; qvga_dev_err(g_sp0821->dev, "%s: sp0821 light=%d, %d\n", __func__, light, reg_data1); len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", light); return len; } static ssize_t sp0821_set_light(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { ssize_t ret; unsigned int state; ret = kstrtouint(buf, 10, &state); if (ret) { qvga_dev_err(g_sp0821->dev, "%s: fail to change str to int\n", __func__); return ret; } if (state == 0) sp0821_hw_off(g_sp0821); /*OFF*/ else sp0821_hw_on(g_sp0821); /*ON*/ return len; } static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, sp0821_get_reg, sp0821_set_reg); static DEVICE_ATTR(cam_name, S_IWUSR | S_IRUGO, sp0821_get_name, NULL); static DEVICE_ATTR(light, S_IWUSR | S_IRUGO, sp0821_get_light, sp0821_set_light); static struct attribute *sp0821_attributes[] = { &dev_attr_reg.attr, &dev_attr_cam_name.attr, &dev_attr_light.attr, NULL }; static struct attribute_group sp0821_attribute_group = { .attrs = sp0821_attributes }; static void sp0821_parse_gpio_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (sp0821->reset_gpio < 0) { qvga_dev_err(sp0821->dev, "%s: no reset gpio provided, hardware reset unavailable\n", __func__); sp0821->reset_gpio = -1; } else { qvga_dev_info(sp0821->dev, "%s: reset gpio provided ok\n", __func__); } sp0821->reset_gpio1 = of_get_named_gpio(np, "reset-gpio1", 0); if (sp0821->reset_gpio1 < 0) { qvga_dev_err(sp0821->dev, "%s: no reset gpio1 provided, hardware reset unavailable\n", __func__); sp0821->reset_gpio1 = -1; } else { qvga_dev_info(sp0821->dev, "%s: reset gpio1 provided ok\n", __func__); } } static void sp0821_parse_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821_parse_gpio_dt(sp0821, np); } /**************************************************************************** * sp0821 i2c driver *****************************************************************************/ static int sp0821_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *np = client->dev.of_node; struct pinctrl *sp0821_pinctrl = NULL; struct pinctrl_state *set_state = NULL; struct pinctrl_state *sp0821_mclk_on = NULL; struct pinctrl_state *sp0821_mclk_off = NULL; struct sp0821 *sp0821 = NULL; struct class *qvga_class; struct device *dev; int ret = -1; pr_err("scw %s enter , i2c%d@0x%02x\n", __func__, client->adapter->nr, client->addr); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { qvga_dev_err(&client->dev, "%s: check_functionality failed\n", __func__); ret = -ENODEV; goto exit_check_functionality_failed; } sp0821 = sp0821_malloc_init(client); g_sp0821 = sp0821; sp0821->i2c_seq = sp0821->i2c_client->adapter->nr; sp0821->i2c_addr = sp0821->i2c_client->addr; if (sp0821 == NULL) { dev_err(&client->dev, "%s: failed to parse device tree node\n", __func__); ret = -ENOMEM; goto exit_devm_kzalloc_failed; } sp0821->dev = &client->dev; i2c_set_clientdata(client, sp0821); sp0821_parse_dt(sp0821, np); if (gpio_is_valid(sp0821->reset_gpio)) { ret = devm_gpio_request_one(&client->dev, sp0821->reset_gpio, GPIOF_OUT_INIT_LOW, "sp0821_rst"); if (ret) { qvga_dev_err(&client->dev, "%s: rst request failed\n", __func__); goto exit_gpio_request_failed; } } if (gpio_is_valid(sp0821->reset_gpio1)) { ret = devm_gpio_request_one(&client->dev, sp0821->reset_gpio1, GPIOF_OUT_INIT_LOW, "sp0821_rst1"); if (ret) { qvga_dev_err(&client->dev, "%s: rst1 request failed\n", __func__); goto exit_gpio_request_failed; } } sp0821_pinctrl = devm_pinctrl_get(&client->dev); if (IS_ERR_OR_NULL(sp0821_pinctrl)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl not defined\n", __func__); } else { set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_ON); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk on\n", __func__); } else { sp0821_mclk_on = set_state; } set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_OFF); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk off\n", __func__); } else { sp0821_mclk_off = set_state; } ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_off); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk off\n", __func__); } } //power on camera sp0821_hw_off_reset1(sp0821); mdelay(5); sp0821_vcam_control(sp0821, true); mdelay(1); ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_on); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk on\n", __func__); } sp0821_hw_on_reset1(sp0821); sp0821_hw_on_reset(sp0821); mdelay(5); // sp0821->hwen_flag = 1; /* sp0821 sensor id */ ret = sp0821_GetSensorID(sp0821); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821read_sensorid failed ret=%d\n", __func__, ret); goto exit_i2c_check_id_failed; } //power off camera sp0821_vcam_control(sp0821, false); sp0821_hw_off_reset1(sp0821); // sp0821_Init(sp0821); qvga_class = class_create(THIS_MODULE, "qvga_cam"); dev = device_create(qvga_class, NULL, client->dev.devt, NULL, "qvga_depth"); ret = sysfs_create_group(&dev->kobj, &sp0821_attribute_group); if (ret < 0) { qvga_dev_err(&client->dev, "%s failed to create sysfs nodes\n", __func__); } return 0; exit_i2c_check_id_failed: sp0821_vcam_control(sp0821, false); sp0821_hw_off_reset1(sp0821); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); exit_gpio_request_failed: devm_kfree(&client->dev, sp0821); sp0821 = NULL; exit_devm_kzalloc_failed: exit_check_functionality_failed: return ret; } static int sp0821_i2c_remove(struct i2c_client *client) { struct sp0821 *sp0821 = i2c_get_clientdata(client); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); if (gpio_is_valid(sp0821->reset_gpio1)) devm_gpio_free(&client->dev, sp0821->reset_gpio1); devm_kfree(&client->dev, sp0821); sp0821 = NULL; return 0; } static const struct of_device_id sp0821_of_match[] = { {.compatible = "sc,sp_sp0821_yuv"}, {}, }; static struct i2c_driver sp0821_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = "sp_sp0821_yuv", .of_match_table = sp0821_of_match, }, .probe = sp0821_i2c_probe, .remove = sp0821_i2c_remove, }; static int __init sp0821_yuv_init(void) { int ret; pr_info("%s: driver version: %s\n", __func__, SP0821_DRIVER_VERSION); ret = i2c_add_driver(&sp0821_i2c_driver); if (ret) { pr_info("****[%s] Unable to register driver (%d)\n", __func__, ret); return ret; } return 0; } static void __exit sp0821_yuv_exit(void) { pr_info("%s enter\n", __func__); i2c_del_driver(&sp0821_i2c_driver); } module_init(sp0821_yuv_init); module_exit(sp0821_yuv_exit); MODULE_AUTHOR("wangyuqiu@longcheer.com>"); MODULE_DESCRIPTION("sp0821 yuv driver"); MODULE_LICENSE("GPL v2"); 如果以这个函数为主体,想要将/* * sp0821.c sp0821 yuv module * * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/irq.h> #include <linux/firmware.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/gameport.h> #include <linux/moduleparam.h> #include <linux/mutex.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/ktime.h> #include <linux/kthread.h> #include <linux/regulator/consumer.h> #include "sp_sp0821_yuv.h" #include "../../../aw37004/aw37004.h" #include <soc/oplus/system/oplus_project.h> #include <linux/videodev2.h> #include <linux/cdev.h> #include <linux/atomic.h> #include <linux/types.h> extern void ISP_MCLK3_EN (bool En); extern int aw37004_camera_power_up(int out_iotype, unsigned int out_val); #define kal_uint16 unsigned short #define kal_uint32 unsigned int /***************************************************************** * sp0821 marco ******************************************************************/ #define SP0821_DRIVER_VERSION "V2.0" #define SP0821_PRODUCT_NUM 4 #define SP0821_PRODUCT_NAME_LEN 8 #define SP0821_SENSOR_ID 0x9c #define SP0821_MCLK_ON "sp0821_mclk_on" #define SP0821_MCLK_OFF "sp0821_mclk_off" #define PAGE_SIZE = 5 /***************************************************************** * sp0821 global global variable ******************************************************************/ static unsigned char read_reg_id = 0; static unsigned char read_reg_value = 0; static int read_reg_flag = 0; static int driver_flag = 0; struct sp0821 *g_sp0821 = NULL; /********************************************************** * i2c write and read **********************************************************/ static int sp0821_i2c_write(struct sp0821 *sp0821, unsigned char reg_addr, unsigned char reg_data) { int ret = -1; unsigned char cnt = 0; while (cnt < 1) { ret = i2c_smbus_write_byte_data(sp0821->i2c_client, reg_addr, reg_data); if (ret < 0) { qvga_dev_err(sp0821->dev, "%s: i2c_write cnt=%d error=%d\n", __func__, cnt, ret); } else { break; } cnt++; msleep(2); } return ret; } static int sp0821_i2c_read(struct sp0821 *sp0821, unsigned char reg_addr, unsigned char *reg_data) { int ret = -1; unsigned char cnt = 0; while (cnt < 1) { ret = i2c_smbus_read_byte_data(sp0821->i2c_client, reg_addr); if (ret < 0) { qvga_dev_err(sp0821->dev, "%s: i2c_read cnt=%d error=%d\n", __func__, cnt, ret); } else { *reg_data = ret; break; } cnt++; msleep(2); } return ret; } static struct sp0821 *sp0821_malloc_init(struct i2c_client *client) { struct sp0821 *sp0821 = devm_kzalloc(&client->dev, sizeof(struct sp0821), GFP_KERNEL); if (sp0821 == NULL) { qvga_dev_err(&client->dev, "%s: devm_kzalloc failed.\n", __func__); return NULL; } sp0821->i2c_client = client; pr_info("%s enter , client_addr = 0x%02x\n", __func__, sp0821->i2c_client->addr); return sp0821; } #if 1 void sp0821_Init(struct sp0821 *sp0821) { /*SYS*/ sp0821_i2c_write(sp0821, 0x30, 0x00); qvga_dev_info(sp0821->dev, "%s zho0 sp0821 reg[0x30]\n", __func__); sp0821_i2c_write(sp0821, 0x32, 0x00); sp0821_i2c_write(sp0821, 0x03, 0x01); sp0821_i2c_write(sp0821, 0x04, 0x2c); sp0821_i2c_write(sp0821, 0x24, 0x80); sp0821_i2c_write(sp0821, 0x9b, 0x32); sp0821_i2c_write(sp0821, 0xd7, 0x00); sp0821_i2c_write(sp0821, 0xc5, 0xc7); sp0821_i2c_write(sp0821, 0xc6, 0xe2); sp0821_i2c_write(sp0821, 0xe7, 0x03); qvga_dev_info(sp0821->dev, "%s zho1 sp0821 reg[0xe7]\n", __func__); sp0821_i2c_write(sp0821, 0x32, 0x00); sp0821_i2c_write(sp0821, 0x32, 0x01); sp0821_i2c_write(sp0821, 0x32, 0x00); sp0821_i2c_write(sp0821, 0xbf, 0x0f); sp0821_i2c_write(sp0821, 0xba, 0x5a); sp0821_i2c_write(sp0821, 0xbb, 0x69); sp0821_i2c_write(sp0821, 0xe7, 0x00); sp0821_i2c_write(sp0821, 0x32, 0x07); sp0821_i2c_write(sp0821, 0x31, 0x03); sp0821_i2c_write(sp0821, 0x19, 0x04); sp0821_i2c_write(sp0821, 0x2c, 0x0f); sp0821_i2c_write(sp0821, 0x2e, 0x7c); qvga_dev_info(sp0821->dev, "%s zho2 sp0821 reg[0x2e]\n", __func__); sp0821_i2c_write(sp0821, 0x30, 0x00); sp0821_i2c_write(sp0821, 0x28, 0x2e); sp0821_i2c_write(sp0821, 0x29, 0x1f); sp0821_i2c_write(sp0821, 0x0f, 0x30); sp0821_i2c_write(sp0821, 0x14, 0xb0); sp0821_i2c_write(sp0821, 0x38, 0x50); sp0821_i2c_write(sp0821, 0x39, 0x52); sp0821_i2c_write(sp0821, 0x3a, 0x60); sp0821_i2c_write(sp0821, 0x3b, 0x10); sp0821_i2c_write(sp0821, 0x3c, 0xe0); sp0821_i2c_write(sp0821, 0x85, 0x01); sp0821_i2c_write(sp0821, 0xe0, 0x02); qvga_dev_info(sp0821->dev, "%s zho3 sp0821 reg[0xe0]\n", __func__); sp0821_i2c_write(sp0821, 0xe5, 0x60); sp0821_i2c_write(sp0821, 0xf5, 0x02); sp0821_i2c_write(sp0821, 0xf1, 0x03); sp0821_i2c_write(sp0821, 0xf3, 0x40); sp0821_i2c_write(sp0821, 0x41, 0x00); sp0821_i2c_write(sp0821, 0x05, 0x00); sp0821_i2c_write(sp0821, 0x06, 0x00); sp0821_i2c_write(sp0821, 0x07, 0x00); sp0821_i2c_write(sp0821, 0x08, 0x00); sp0821_i2c_write(sp0821, 0x09, 0x00); sp0821_i2c_write(sp0821, 0x0a, 0x34); sp0821_i2c_write(sp0821, 0x0D, 0x01); sp0821_i2c_write(sp0821, 0xc8, 0x10); sp0821_i2c_write(sp0821, 0x29, 0x1e); qvga_dev_info(sp0821->dev, "%s zho4 sp0821 reg[0x29]\n", __func__); sp0821_i2c_write(sp0821, 0xa2, 0x26); sp0821_i2c_write(sp0821, 0xa3, 0x02); sp0821_i2c_write(sp0821, 0xa4, 0x32); sp0821_i2c_write(sp0821, 0xa5, 0x00); sp0821_i2c_write(sp0821, 0xa8, 0x32); sp0821_i2c_write(sp0821, 0xa9, 0x00); sp0821_i2c_write(sp0821, 0xaa, 0x01); sp0821_i2c_write(sp0821, 0xab, 0x00); sp0821_i2c_write(sp0821, 0x4c, 0x80); sp0821_i2c_write(sp0821, 0x4d, 0x80); sp0821_i2c_write(sp0821, 0xa6, 0xf0); sp0821_i2c_write(sp0821, 0xa7, 0x20); sp0821_i2c_write(sp0821, 0xac, 0xf0); sp0821_i2c_write(sp0821, 0xad, 0x20); sp0821_i2c_write(sp0821, 0x8a, 0x3e); qvga_dev_info(sp0821->dev, "%s zho5 sp0821 reg[0x8a]\n", __func__); sp0821_i2c_write(sp0821, 0x8b, 0x30); sp0821_i2c_write(sp0821, 0x8c, 0x2a); sp0821_i2c_write(sp0821, 0x8d, 0x26); sp0821_i2c_write(sp0821, 0x8e, 0x26); sp0821_i2c_write(sp0821, 0x8f, 0x24); sp0821_i2c_write(sp0821, 0x90, 0x24); sp0821_i2c_write(sp0821, 0x91, 0x22); sp0821_i2c_write(sp0821, 0x92, 0x22); sp0821_i2c_write(sp0821, 0x93, 0x22); sp0821_i2c_write(sp0821, 0x94, 0x20); sp0821_i2c_write(sp0821, 0x95, 0x20); sp0821_i2c_write(sp0821, 0x96, 0x20); sp0821_i2c_write(sp0821, 0x17, 0x88); sp0821_i2c_write(sp0821, 0x18, 0x80); sp0821_i2c_write(sp0821, 0x4e, 0x78); sp0821_i2c_write(sp0821, 0x4f, 0x78); sp0821_i2c_write(sp0821, 0x58, 0x8a); sp0821_i2c_write(sp0821, 0x59, 0xa8); sp0821_i2c_write(sp0821, 0x5a, 0x80); qvga_dev_info(sp0821->dev, "%s zho6 sp0821 reg[0x5a]\n", __func__); sp0821_i2c_write(sp0821, 0xca, 0x00); sp0821_i2c_write(sp0821, 0x86, 0x08); sp0821_i2c_write(sp0821, 0x87, 0x0f); sp0821_i2c_write(sp0821, 0x88, 0x30); sp0821_i2c_write(sp0821, 0x89, 0x45); sp0821_i2c_write(sp0821, 0x9e, 0x94); sp0821_i2c_write(sp0821, 0x9f, 0x88); sp0821_i2c_write(sp0821, 0x97, 0x84); sp0821_i2c_write(sp0821, 0x98, 0x88); sp0821_i2c_write(sp0821, 0x99, 0x74); sp0821_i2c_write(sp0821, 0x9a, 0x84); sp0821_i2c_write(sp0821, 0xa0, 0x7c); sp0821_i2c_write(sp0821, 0xa1, 0x78); sp0821_i2c_write(sp0821, 0x9d, 0x09); sp0821_i2c_write(sp0821, 0xB1, 0x04); sp0821_i2c_write(sp0821, 0xb3, 0x00); qvga_dev_info(sp0821->dev, "%s zho7 sp0821 reg[0xb3]\n", __func__); sp0821_i2c_write(sp0821, 0x47, 0x40); sp0821_i2c_write(sp0821, 0xb8, 0x04); sp0821_i2c_write(sp0821, 0xb9, 0x28); sp0821_i2c_write(sp0821, 0x3f, 0x18); sp0821_i2c_write(sp0821, 0xc1, 0xff); sp0821_i2c_write(sp0821, 0xc2, 0x40); sp0821_i2c_write(sp0821, 0xc3, 0xff); sp0821_i2c_write(sp0821, 0xc4, 0x40); sp0821_i2c_write(sp0821, 0xc5, 0xc7); sp0821_i2c_write(sp0821, 0xc6, 0xe2); sp0821_i2c_write(sp0821, 0xc7, 0xef); sp0821_i2c_write(sp0821, 0xc8, 0x10); sp0821_i2c_write(sp0821, 0x50, 0x2a); sp0821_i2c_write(sp0821, 0x51, 0x2a); sp0821_i2c_write(sp0821, 0x52, 0x2f); sp0821_i2c_write(sp0821, 0x53, 0xcf); sp0821_i2c_write(sp0821, 0x54, 0xd0); qvga_dev_info(sp0821->dev, "%s zho8 sp0821 reg[0x54]\n", __func__); sp0821_i2c_write(sp0821, 0x5c, 0x1e); sp0821_i2c_write(sp0821, 0x5d, 0x21); sp0821_i2c_write(sp0821, 0x5e, 0x1a); sp0821_i2c_write(sp0821, 0x5f, 0xe9); sp0821_i2c_write(sp0821, 0x60, 0x98); sp0821_i2c_write(sp0821, 0xcb, 0x3f); sp0821_i2c_write(sp0821, 0xcc, 0x3f); sp0821_i2c_write(sp0821, 0xcd, 0x3f); sp0821_i2c_write(sp0821, 0xce, 0x85); sp0821_i2c_write(sp0821, 0xcf, 0xff); sp0821_i2c_write(sp0821, 0x79, 0x5a); sp0821_i2c_write(sp0821, 0x7a, 0xDC); sp0821_i2c_write(sp0821, 0x7b, 0x0A); sp0821_i2c_write(sp0821, 0x7c, 0xFD); sp0821_i2c_write(sp0821, 0x7d, 0x46); sp0821_i2c_write(sp0821, 0x7e, 0xFD); sp0821_i2c_write(sp0821, 0x7f, 0xFD); sp0821_i2c_write(sp0821, 0x80, 0xEF); sp0821_i2c_write(sp0821, 0x81, 0x54); qvga_dev_info(sp0821->dev, "%s zho9 sp0821 reg[0x81]\n", __func__); sp0821_i2c_write(sp0821, 0x1b, 0x0a); sp0821_i2c_write(sp0821, 0x1c, 0x0f); sp0821_i2c_write(sp0821, 0x1d, 0x15); sp0821_i2c_write(sp0821, 0x1e, 0x15); sp0821_i2c_write(sp0821, 0x1f, 0x15); sp0821_i2c_write(sp0821, 0x20, 0x1f); sp0821_i2c_write(sp0821, 0x21, 0x2a); sp0821_i2c_write(sp0821, 0x22, 0x2a); sp0821_i2c_write(sp0821, 0x56, 0x49); sp0821_i2c_write(sp0821, 0x1a, 0x14); sp0821_i2c_write(sp0821, 0x34, 0x1f); sp0821_i2c_write(sp0821, 0x82, 0x10); sp0821_i2c_write(sp0821, 0x83, 0x00); qvga_dev_info(sp0821->dev, "%s zho10 sp0821 reg[0x83]\n", __func__); sp0821_i2c_write(sp0821, 0x84, 0xff); sp0821_i2c_write(sp0821, 0xd7, 0x50); sp0821_i2c_write(sp0821, 0xd8, 0x1a); sp0821_i2c_write(sp0821, 0xd9, 0x20); sp0821_i2c_write(sp0821, 0xc9, 0x1f); sp0821_i2c_write(sp0821, 0xbf, 0x33); sp0821_i2c_write(sp0821, 0xba, 0x37); sp0821_i2c_write(sp0821, 0xbb, 0x38); qvga_dev_info(sp0821->dev, "%s zho11 sp0821 reg[0xbb]\n", __func__); } /* sensor_init */ #endif int sp0821_GetSensorID(struct sp0821 *sp0821) { int retry = 5; int len; unsigned char reg_data = 0x00; //check if sensor ID correct do { len = sp0821_i2c_read(sp0821, 0x02, &reg_data); qvga_dev_err(sp0821->dev, "drv-%s: Read MSB Sensor ID sucess = 0x%02x\n", __func__, reg_data); // if (reg_data == SP0821_SENSOR_ID) { if (1) { qvga_dev_err(sp0821->dev, "drv-%s: Read Sensor ID sucess = 0x%02x\n", __func__, reg_data); driver_flag = 1; return 0; } else { qvga_dev_err(sp0821->dev, "rv-%s: Read Sensor ID Fail = 0x%02x\n", __func__, reg_data); driver_flag = 0; } mdelay(10); retry--; } while (retry > 0); return -1; } static void sp0821_vcam_control(struct sp0821 *sp0821, bool flag) { struct regulator *vcama; struct regulator *vcamio; //struct regulator *vcamd; int ret; int ret1; qvga_dev_info(sp0821->dev, "%s weibiao_enter\n", __func__); // vcama = regulator_get(sp0821->dev,"vcama"); // if (IS_ERR(vcama)) { // qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); // regulator_put(vcama); // return; // } // if (flag) { // regulator_set_voltage(vcama, 2800000, 2800000); // ret = regulator_enable(vcama); // } else { // regulator_disable(vcama); // } if (flag) { ret1 = aw37004_camera_power_up(2, 2800); if (ret1 == 0) { qvga_dev_err(sp0821->dev, "%s get regulator vcama success\n", __func__); } else { qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); } } vcamio = regulator_get(sp0821->dev,"vcamio"); if (IS_ERR(vcamio)) { qvga_dev_err(sp0821->dev, "%s get regulator vcamio failed\n", __func__); regulator_put(vcamio); return; } else { qvga_dev_err(sp0821->dev, "%s get regulator vcama success\n", __func__); } if (flag) { regulator_set_voltage(vcamio, 1800000, 1800000); ret = regulator_enable(vcamio); } else { regulator_disable(vcamio); } // vcamd = regulator_get(sp0821->dev,"vcamd"); // if (IS_ERR(vcamd)) { // qvga_dev_err(sp0821->dev, "%s get regulator vcamd failed\n", __func__); // regulator_put(vcamd); // return; // } // if (flag) { // regulator_set_voltage(vcamd, 1200000, 1200000); // regulator_enable(vcamd); // } else { // regulator_disable(vcamd); // } // return; } static void sp0821_hw_on_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 0); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 1); udelay(100); gpio_set_value_cansleep(sp0821->reset_gpio, 0); } } static void sp0821_hw_off_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 0); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 1); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 0); } } static void sp0821_hw_on(struct sp0821 *sp0821) { sp0821_hw_on_reset(sp0821); sp0821_Init(sp0821); sp0821->hwen_flag = 1; } static void sp0821_hw_off(struct sp0821 *sp0821) { sp0821_hw_off_reset(sp0821); sp0821->hwen_flag = 0; } static ssize_t sp0821_get_reg(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (read_reg_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "The reg 0x%02X value is 0x%02X\n", read_reg_id, read_reg_value); read_reg_flag = 0; read_reg_id = 0; read_reg_value = 0; } else { len += snprintf(buf + len, PAGE_SIZE - len, "Please echo reg id into reg\n"); } return len; } static ssize_t sp0821_set_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { unsigned int databuf[2] = { 0 }; unsigned char reg_data = 0x00; int length; //struct sp0821 *sp0821 = dev_get_drvdata(dev); if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { sp0821_i2c_write(g_sp0821, databuf[0], databuf[1]); } else if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 1) { length = sp0821_i2c_read(g_sp0821, databuf[0], &reg_data); read_reg_id = databuf[0]; read_reg_value = reg_data; read_reg_flag = 1; } return len; } static ssize_t sp0821_get_name(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (driver_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "sp_sp0821_yuv"); } else { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "none"); } return len; } static ssize_t sp0821_get_light(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; unsigned char reg_data = 0x00; int length; //struct sp0821 *sp0821 = dev_get_drvdata(dev); length = sp0821_i2c_read(g_sp0821, 0xb0, &reg_data); len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", reg_data); return len; } static ssize_t sp0821_set_light(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { ssize_t ret; unsigned int state; //struct sp0821 *sp0821 = dev_get_drvdata(dev); ret = kstrtouint(buf, 10, &state); if (ret) { qvga_dev_err(g_sp0821->dev, "%s: fail to change str to int\n", __func__); return ret; } if (state == 0) sp0821_hw_off(g_sp0821); /*OFF*/ else sp0821_hw_on(g_sp0821); /*ON*/ return len; } static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, sp0821_get_reg, sp0821_set_reg); static DEVICE_ATTR(cam_name, S_IWUSR | S_IRUGO, sp0821_get_name, NULL); static DEVICE_ATTR(light, S_IWUSR | S_IRUGO, sp0821_get_light, sp0821_set_light); static struct attribute *sp0821_attributes[] = { &dev_attr_reg.attr, &dev_attr_cam_name.attr, &dev_attr_light.attr, NULL }; static struct attribute_group sp0821_attribute_group = { .attrs = sp0821_attributes }; static void sp0821_parse_gpio_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (sp0821->reset_gpio < 0) { qvga_dev_err(sp0821->dev, "%s: no reset gpio provided, hardware reset unavailable\n", __func__); sp0821->reset_gpio = -1; } else { qvga_dev_info(sp0821->dev, "%s: reset gpio provided ok\n", __func__); } } static void sp0821_parse_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821_parse_gpio_dt(sp0821, np); } /**************************************************************************** * sp0821 i2c driver *****************************************************************************/ static int sp0821_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *np = client->dev.of_node; struct pinctrl *sp0821_pinctrl = NULL; struct pinctrl_state *set_state = NULL; struct pinctrl_state *sp0821_mclk_on = NULL; struct pinctrl_state *sp0821_mclk_off = NULL; struct sp0821 *sp0821 = NULL; struct class *qvga_class; struct device *dev; int ret = -1; pr_err("scw %s enter , i2c%d@0x%02x\n", __func__, client->adapter->nr, client->addr); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { qvga_dev_err(&client->dev, "%s: check_functionality failed\n", __func__); ret = -ENODEV; goto exit_check_functionality_failed; } sp0821 = sp0821_malloc_init(client); g_sp0821 = sp0821; sp0821->i2c_seq = sp0821->i2c_client->adapter->nr; sp0821->i2c_addr = sp0821->i2c_client->addr; if (sp0821 == NULL) { qvga_dev_err(&client->dev, "%s: failed to parse device tree node\n", __func__); ret = -ENOMEM; goto exit_devm_kzalloc_failed; } sp0821->dev = &client->dev; i2c_set_clientdata(client, sp0821); sp0821_parse_dt(sp0821, np); if (gpio_is_valid(sp0821->reset_gpio)) { ret = devm_gpio_request_one(&client->dev, sp0821->reset_gpio, GPIOF_OUT_INIT_LOW, "sp0821_rst");//sp if (ret) { qvga_dev_err(&client->dev, "%s: rst request failed\n", __func__); goto exit_gpio_request_failed; } } sp0821_pinctrl = devm_pinctrl_get(&client->dev); if (IS_ERR_OR_NULL(sp0821_pinctrl)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl not defined\n", __func__); } else { set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_ON); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk on\n", __func__); } else { sp0821_mclk_on = set_state; } set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_OFF); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk off\n", __func__); } else { sp0821_mclk_off = set_state; } ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_off); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk off\n", __func__); } } //power on camera sp0821_vcam_control(sp0821, true); ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_on); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk on\n", __func__); } mdelay(5); sp0821_hw_on_reset(sp0821); // sp0821->hwen_flag = 1; /* sp0821 sensor id */ ret = sp0821_GetSensorID(sp0821); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821read_sensorid failed ret=%d\n", __func__, ret); goto exit_i2c_check_id_failed; } //power off camera sp0821_vcam_control(sp0821, false); // sp0821_Init(sp0821); qvga_class = class_create(THIS_MODULE, "qvga_cam"); dev = device_create(qvga_class, NULL, client->dev.devt, NULL, "qvga_depth"); ret = sysfs_create_group(&dev->kobj, &sp0821_attribute_group); if (ret < 0) { qvga_dev_err(&client->dev, "%s failed to create sysfs nodes\n", __func__); } return 0; exit_i2c_check_id_failed: sp0821_vcam_control(sp0821, false); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); exit_gpio_request_failed: devm_kfree(&client->dev, sp0821); sp0821 = NULL; exit_devm_kzalloc_failed: exit_check_functionality_failed: return ret; } static int sp0821_i2c_remove(struct i2c_client *client) { struct sp0821 *sp0821 = i2c_get_clientdata(client); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); devm_kfree(&client->dev, sp0821); sp0821 = NULL; return 0; } static const struct of_device_id sp0821_of_match[] = { {.compatible = "sp,sp_sp0821_yuv"}, {}, }; static struct i2c_driver sp0821_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = "sp_sp0821_yuv", .of_match_table = sp0821_of_match, }, .probe = sp0821_i2c_probe, .remove = sp0821_i2c_remove, }; static int __init sp0821_yuv_init(void) { int ret; pr_info("%s: driver version: %s\n", __func__, SP0821_DRIVER_VERSION); ret = i2c_add_driver(&sp0821_i2c_driver); if (ret) { pr_info("****[%s] Unable to register driver (%d)\n", __func__, ret); return ret; } return 0; } static void __exit sp0821_yuv_exit(void) { pr_info("%s enter\n", __func__); i2c_del_driver(&sp0821_i2c_driver); } module_init(sp0821_yuv_init); module_exit(sp0821_yuv_exit); MODULE_AUTHOR("wangyuqiu@longcheer.com>"); MODULE_DESCRIPTION("sp0821 yuv driver"); MODULE_LICENSE("GPL v2"); 适配成第一个驱动那样,帮忙生成代码
07-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值