FL2440驱动添加(3)LCD驱动添加学习笔记

发布时间:2024-07-24  

FL2440 LCD内置控制器,320*240 TFT型LCD。


自我理解总结的两种添加驱动模式:

非platform方式添加驱动:


加载驱动:

1,硬件初始化,申请内存,并作地址映射

2,分配设备号,分配结构体

3,注册设备

卸载驱动:

1,释放内存

2,释放结构体,返还设备号

3,注销设备

platform总线方式添加驱动(主流方式):

1.编写设备链 


struct platform_device

{

       const chat *name;

       u32 id;

       struct device dev;

       u32 num_resources;

       struct resources * resources;

};


2,编写驱动链


static struct platform_driver

{

      int (*probe)( struct platform_device*),//探测函数

      int (*remove)( structplatform_device*),//删除函数

       ……

       struct device_driver driver;

};


3,在设备链注册设备和在驱动链注册驱动


int __init xxx_init()

{

.....

platform_device_register();

platform_driver_register();

.....

}


4,反向在驱动链注销驱动,在设备链注销设备


void __exit  xxx_exit()

{

.....

platform_driver_unregister();

platform_device_unregister();

.....

}



开始添加LCD驱动:内核版本linux-3.8.0


1,在arch/arm/mach-s3c24xx/mach-smdk2440.c中修改相关信息平台数据

/* LCD driver info */

static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {

 

    .lcdcon5   = S3C2410_LCDCON5_FRM565|

              S3C2410_LCDCON5_INVVLINE |

              S3C2410_LCDCON5_INVVFRAME |

              S3C2410_LCDCON5_PWREN |

              S3C2410_LCDCON5_HWSWP,

 

    .type      = S3C2410_LCDCON1_TFT,

    .width     = 320,

    .height    = 240,

    .pixclock  = 111111, /* HCLK 60 MHz, divisor 10 */

    .xres      = 480,

    .yres      = 272,

    .bpp       = 16,

    .left_margin    = 38,

    .right_margin   = 20,

    .hsync_len = 30,

    .upper_margin   = 15,

    .lower_margin   = 12,

    .vsync_len = 3,

};

 

static struct s3c2410fb_mach_info smdk2440_fb_info  __initdata = {

    .displays  = &smdk2440_lcd_cfg,

    .num_displays   = 1,

    .default_display = 0,

#if 0
    /* currently setup by downloader */
    .gpccon     = 0xaa940659,
    .gpccon_mask    = 0xffffffff,
    .gpcup      = 0x0000ffff,
    .gpcup_mask = 0xffffffff,
    .gpdcon     = 0xaa84aaa0,
    .gpdcon_mask    = 0xffffffff,
    .gpdup      = 0x0000faff,
    .gpdup_mask = 0xffffffff,
#endif

    .lpcsel    = ((0xCE6) & ~7) | 1<<1,

};



2,由于在arch/arm/plat-samsung/devs.c已经定义了LCD的设备以及平台添加函数,如下

/* LCD Controller */

#ifdef CONFIG_PLAT_S3C24XX

static struct resource s3c_lcd_resource[]= {

    [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),

    [1] = DEFINE_RES_IRQ(IRQ_LCD),

};

 

struct platform_device s3c_device_lcd= {

    .name      = "s3c2410-lcd",

    .id    = -1,

    .num_resources  = ARRAY_SIZE(s3c_lcd_resource),

    .resource  = s3c_lcd_resource,

    .dev       = {

        .dma_mask       = &samsung_device_dma_mask,

        .coherent_dma_mask  = DMA_BIT_MASK(32),

    }

};


//平台添加函数

void __init s3c24xx_fb_set_platdata(structs3c2410fb_mach_info *pd)

{  

    struct s3c2410fb_mach_info *npd;

 

    npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);

    if (npd) {

        npd->displays =kmemdup(pd->displays,

            sizeof(struct s3c2410fb_display) * npd->num_displays,

            GFP_KERNEL);

        if (!npd->displays)

            printk(KERN_ERR "no memory forLCD display datan");

    } else {

        printk(KERN_ERR "no memory for LCDplatform datan");

    }

}

#endif /*CONFIG_PLAT_S3C24XX */

 

 

所以在arch/arm/mach-s3c24xx/mach-smdk2440.c只需注册设备:

static struct platform_device *smdk2440_devices[] __initdata = {

    &s3c_device_ohci,

    &s3c_device_lcd,

    &s3c_device_wdt,

    &s3c_device_i2c0,

    &s3c_device_iis,

    &s3c_device_dm9000,

    &s3c_device_adc,   

    &s3c_device_ts,

    &s3c_device_rtc,

    &globalfifo_device

};

 

通过调用smdk2440_machine_init添加到设备链,

static void __init smdk2440_machine_init(void)

{

    //调用该函数将上面定义的LCD硬件信息保存到平台数据中

    s3c24xx_fb_set_platdata(&smdk2440_fb_info); 

    s3c_i2c0_set_platdata(NULL);

   

    platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));

    smdk_machine_init();

}

 

跟踪platform_add_devices函数,其实际调用了platform_device_register和platform_device_unregister函数,如下:

在drivers/base/platform.c下定义:

int platform_add_devices(struct platform_device **devs, int num)
{   
    int i, ret = 0;
    
    for (i = 0; i < num; i++) {
        ret = platform_device_register(devs[i]);
        if (ret) { 
            while (--i >= 0)
                platform_device_unregister(devs[i]);
            break;
        }
    }
    
    return ret;
}
EXPORT_SYMBOL_GPL(platform_add_devices);


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>