S3C2410驱动分析之ADC通用驱动(2)

回到s3c_adc_probe函数:339行,设置预分频系统为49。341行,取得ADC中断号。348行,申请中断,注册ADC中断处理函数为s3c_adc_irq。354行,取得ADC时钟。361行,取得ADC I/O内存。368行,使用ioremap得到I/O内存对应的虚拟地址。375行,使能ADC时钟。377 - 382行,设置使用预分频及预分频系统。至此,ADC模块的初始化就完成了。下面我们看客户注册ADC服务的接口函数s3c_adc_register,代码如下:

 

207struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,  208                    void (*select)(struct s3c_adc_client *client,  209                               unsigned int selected),  210                    void (*conv)(struct s3c_adc_client *client,  211                             unsigned d0, unsigned d1,  212                             unsigned *samples_left),  213                    unsigned int is_ts)  214{  215    struct s3c_adc_client *client;  216  217    WARN_ON(!pdev);  218  219    if (!select)  220        select = s3c_adc_default_select;  221  222    if (!pdev)  223        return ERR_PTR(-EINVAL);  224  225    client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);  226    if (!client) {  227        dev_err(&pdev->dev, "no memory for adc client\n");  228        return ERR_PTR(-ENOMEM);  229    }  230  231    client->pdev = pdev;  232    client->is_ts = is_ts;  233    client->select_cb = select;  234    client->convert_cb = conv;  235  236    return client;  237}  


219 - 220行,如果没有指定select回调函数,则使用默认的回调函数s3c_adc_default_select,这个函数的实现没有做任何事情,是个空函数。由这句话可以看出,select回调函数是必须定义的,自己不定义也要使用默认的。而convert回调函数则不是必须定义的。225 - 234行,为client分配空间,并初始化相关成员。236行,返回client。当客户要读取AD转换结果时,可调用s3c_adc_read函数,其定义如下:

 

175int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)  176{  177    DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);  178    int ret;  179  180    client->convert_cb = s3c_convert_done;  181    client->wait = &wake;  182    client->result = -1;  183  184    ret = s3c_adc_start(client, ch, 1);  185    if (ret < 0)  186        goto err;  187  188    ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);  189    if (client->result < 0) {  190        ret = -ETIMEDOUT;  191        goto err;  192    }  193  194    client->convert_cb = NULL;  195    return client->result;  196  197err:  198    return ret;  199}  


175行,第二个参数ch代表要读ADC控制器的哪个通道。177行,定义等待队列头。180行,指定convert回调函数是s3c_convert_done,该函数我们在后面分析。184行,调用s3c_adc_start函数,该函数我们在后面分析,第二个参数代表使用的ADC通道,第三个参数指定采样次数,这里可以看出,使用s3c_adc_read,采样次数均为1。188行,调用wait_event_timeout在等待队列wake上休眠,休眠条件是 client->result >= 0,最长休眠时间为HZ/2。client��convert回调函数s3c_convert_done定义如下:

 

168static void s3c_convert_done(struct s3c_adc_client *client,  169                 unsigned v, unsigned u, unsigned *left)  170{  171    client->result = v;  172    wake_up(client->wait);  173}  


171行,将第二个参数(data0)赋值给client->result。172行,唤醒等待队列中的休眠进程。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://127.0.0.1/wyyfgx.html