/**************************************************************
gpio_to_irq(S5PV210_GPH2(0))
**************************************************************/
4 #define gpio_to_irq __gpio_to_irq
5
6 int __gpio_to_irq(unsigned gpio)
7 {
8 struct gpio_chip *chip;
9 chip = gpio_to_chip(S5PV210_GPH2(0));
static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
{
return gpio_desc[S5PV210_GPH2(0)].chip;
//參考gpio-s5pv210.c中
//samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips)函數
//gpio_desc[id].chip = chip;
}
10 return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO;
11 //s5pv210_gpio_4bit
12 }
int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
{
//獲得gpio_chip結構體所在的父結構體s3c_gpio_chip的指針
struct s3c_gpio_chip *s3c_chip = container_of(chip,struct s3c_gpio_chip, chip);
//獲取虛擬映射機制中定義的終端號
return s3c_chip->irq_base + offset;
#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1)
: ((x) - 16 + S5P_EINT_BASE2))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
#define IRQ_VIC_END S5P_IRQ_VIC3(31)
#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
#define S5P_VIC3_BASE S5P_IRQ(96)
#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET)
#define S5P_IRQ_OFFSET (32)
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x))
#define S5P_VIC0_BASE S5P_IRQ(0)
}
static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
{
.chip = {
.base = S5PV210_GPA0(0),
.ngpio = S5PV210_GPIO_A0_NR,
.label = 'GPA0',
},
},
...............
...............
{
.base = (S5P_VA_GPIO + 0xC40),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(16),
.chip = {
.base = S5PV210_GPH2(0),
.ngpio = S5PV210_GPIO_H2_NR,
.label = 'GPH2',
.to_irq = samsung_gpiolib_to_irq,
},
},
{
.base = (S5P_VA_GPIO + 0xC60),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(24),
.chip = {
.base = S5PV210_GPH3(0),
.ngpio = S5PV210_GPIO_H3_NR,
.label = 'GPH3',
.to_irq = samsung_gpiolib_to_irq,
},
},
};
1 static __init int s5pv210_gpiolib_init(void)
2 {
3 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
4 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL) {
chip->config = &gpio_cfg;
chip->group = gpioint_group++;
}
if (chip->base == NULL)
chip->base = S5PV210_BANK_BASE(i);
}
6 samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
int nr_chips)
{
for (; nr_chips > 0; nr_chips--, chip++)
{
samsung_gpiolib_add_4bit(chip);
void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = samsung_gpiolib_4bit_input;
chip->chip.direction_output = samsung_gpiolib_4bit_output;
chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
}
s3c_gpiolib_add(chip);
__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
{
//將s3c_gpio_chip 結構體變量s5pv210_gpio_4bit數組中的每一個數組變量 '.chip'傳遞給gpio_chip結構體指針gc
struct gpio_chip *gc = &chip->chip;
//gc = {
// .base = S5PV210_GPH2(0),
// .ngpio = S5PV210_GPIO_H2_NR,
// .label = 'GPH2',
// .to_irq = samsung_gpiolib_to_irq,
// },
int ret;
spin_lock_init(&chip->lock);
//給gc結構體指針其他結構體成員賦值
if (!gc->direction_input)
gc->direction_input = s3c_gpiolib_input;
if (!gc->direction_output)
gc->direction_output = s3c_gpiolib_output;
if (!gc->set)
gc->set = s3c_gpiolib_set;
if (!gc->get)
gc->get = s3c_gpiolib_get;
#ifdef CONFIG_PM
if (chip->pm != NULL) {
if (!chip->pm->save || !chip->pm->resume)
printk(KERN_ERR 'gpio: %s has missing PM functionsn',
gc->label);
} else
printk(KERN_ERR 'gpio: %s has no PM functionn', gc->label);
#endif
// gpiochip_add() prints own failure message on error.
ret = gpiochip_add(gc);
int gpiochip_add(struct gpio_chip *chip){
unsigned long flags; int status = 0; unsigned id;
int base = chip->base; //base = S5PV210_GPH2(0)
//查看獲得的gpio_chip結構體指針基址和范圍是否在有效范圍之內
if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))
&& base >= 0) {
status = -EINVAL;
goto fail;
}
spin_lock_irqsave(&gpio_lock, flags);
if (base < 0) {
base = gpiochip_find_base(chip->ngpio);
if (base < 0) {
status = base;
goto unlock;
}
chip->base = base;
}
//these GPIO numbers must not be managed by another gpio_chip
//遍歷某個GPIO端口組的所有IO,如:S5PV210_GPH2端口組的8個IO口S5PV210_GPH2(0)~(7)
for (id = base; id < base + chip->ngpio; id++)
{
//正常狀態gpio_desc[base].chip未被初始化,所以各個成員為NULL
if (gpio_desc[id].chip != NULL) {
status = -EBUSY;
break;
}
}
if (status == 0) {
for (id = base; id < base + chip->ngpio; id++) {
gpio_desc[id].chip = chip;
//至此完成gpio_desc[S5PV210_GPH2(0)].chip的賦值,作為返回值在gpio_to_chip()中返回
// REVISIT: most hardware initializes GPIOs as
* inputs (often with pullups enabled) so power
* usage is minimized. Linux code should set the
* gpio direction first thing; but until it does,
* we may expose the wrong direction in sysfs.
上一篇:Linux嵌入式學習-ds18b20驅動
下一篇:make: Warning: File `led.c' has modification time 15 s in the future
推薦閱讀最新更新時間:2025-04-23 20:10

設計資源 培訓 開發板 精華推薦
- OP184FSZ 電阻與輸入串聯的典型應用將過壓電流限制在安全值
- 16 位、100 kSPS、低功耗數據采集系統,針對高達 1 kHz 的亞奈奎斯特輸入信號進行了優化
- LTM4643MPV 4V 至 20V 輸入、四路 0.9V、1V、1.2V 和 1.5V 輸出 DC/DC 降壓穩壓器的典型應用
- 【畢設】一轉四TTL2.0
- LT8570IMS8E-1 1.5MHz、5V 至 12V 輸出升壓轉換器的典型應用
- AM2G-0509DZ ±9V 2 瓦 DC/DC 轉換器的典型應用
- LX7186A 1.4MHz、1A 同步降壓轉換器的典型應用
- MC33171DR2G 單+5V 交流耦合同相放大器典型應用
- FUSB252GEVB:FSUSB252 評估板
- LTC3805,非隔離式 36V 至 72V 至 3.3V 3A 反激式轉換器