pxa27x 키패드 구조체 보고있는데요 ~ 질문있습니다~
키패드 드라이버 소스를 보고있는데요 ㅎ
pxa27x_keypad 구조체가 아래와 같이 정의되어있더라구요
struct pxa27x_keypad {
struct pxa27x_keypad_platform_data *pdata;
struct clk *clk;
struct input_dev *input_dev;
void __iomem *mmio_base;
int irq;
unsigned short keycodes[MAX_KEYPAD_KEYS];
int rotary_rel_code[2];
/* state row bits of each column scan */
uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
uint32_t direct_key_state;
unsigned int direct_key_mask;
};
여기서 clk 구조체와 iunput_dev 구조체, 그리고 mmio_base 가
어떤 용도로 쓰이기 위해 함께 있는지 궁금합니다~
probe() 함수를 보면 아래와 같은데, 정확한 개념이 안스네요~
static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
{
struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data;
struct pxa27x_keypad *keypad;
struct input_dev *input_dev;
struct resource *res;
int irq, error;
if (pdata == NULL) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get keypad irq\n");
return -ENXIO;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "failed to get I/O memory\n");
return -ENXIO;
}
keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
input_dev = input_allocate_device();
if (!keypad || !input_dev) {
dev_err(&pdev->dev, "failed to allocate memory\n");
error = -ENOMEM;
goto failed_free;
}
keypad->pdata = pdata;
keypad->input_dev = input_dev;
keypad->irq = irq;
res = request_mem_region(res->start, resource_size(res), pdev->name);
if (res == NULL) {
dev_err(&pdev->dev, "failed to request I/O memory\n");
error = -EBUSY;
goto failed_free;
}
keypad->mmio_base = ioremap(res->start, resource_size(res));
if (keypad->mmio_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
error = -ENXIO;
goto failed_free_mem;
}
keypad->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(keypad->clk)) {
dev_err(&pdev->dev, "failed to get keypad clock\n");
error = PTR_ERR(keypad->clk);
goto failed_free_io;
}
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->open = pxa27x_keypad_open;
input_dev->close = pxa27x_keypad_close;
input_dev->dev.parent = &pdev->dev;
input_dev->keycode = keypad->keycodes;
input_dev->keycodesize = sizeof(keypad->keycodes[0]);
input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
input_set_drvdata(input_dev, keypad);
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
pxa27x_keypad_build_keycode(keypad);
if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
(pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
input_dev->evbit[0] |= BIT_MASK(EV_REL);
}
error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED,
pdev->name, keypad);
if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n");
goto failed_put_clk;
}
/* Register the input device */
error = input_register_device(input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
goto failed_free_irq;
}
platform_set_drvdata(pdev, keypad);
device_init_wakeup(&pdev->dev, 1);
return 0;
failed_free_irq:
free_irq(irq, pdev);
failed_put_clk:
clk_put(keypad->clk);
failed_free_io:
iounmap(keypad->mmio_base);
failed_free_mem:
release_mem_region(res->start, resource_size(res));
failed_free:
input_free_device(input_dev);
kfree(keypad);
return error;
}
답변
input_dev구조체:
input device를 등록하는 용도로 사용됩니다.
이 구조체에 이런저런 값을 설정하면 되구요.
user mode에서는
/dev/input/event* 등의 경로를 통해 접근가능하게 됩니다.
mouse, keyboard 등이 input device로 등록됩니다.
clk 구조체:
일종의 timer 비슷한 것을 등록하는데에 사용됩니다.
interrupt 후에, polling을 하기 위해 clk을 쓰지 싶습니다.
mmio_base :
해당 driver가 (또는 device가) 어떤 address에 mapping되어 있는지, (또는 사용하는지)
를 kernel에 등록합니다.
이걸 등록 안하면, 사용할때의 가상주소와 실제 물리주소와의 주소고정이
풀어질 수 있기 때문에, 이걸 해 주어야 합니다.
감사합니다~!
몇가지 clk에 대해서 질문이 있는데요~
open함수와 close함수를 보면 중간에
static int pxa27x_keypad_open(struct input_dev *dev)
{
struct pxa27x_keypad *keypad = input_get_drvdata(dev);
/* Enable unit clock */
clk_enable(keypad->clk);
pxa27x_keypad_config(keypad);
return 0;
}
static void pxa27x_keypad_close(struct input_dev *dev)
{
struct pxa27x_keypad *keypad = input_get_drvdata(dev);
/* Disable clock unit */
clk_disable(keypad->clk);
}
이런식으로 clk_enable 시키고 clk_disable 시키는게 보이는데,
이 clk이란놈이 인터럽트와 함께 어떤 메커니즘으로 수행되는지 궁금합니다~
댓글 달기