芯片:freescale Mpc8308
当前uboot版本:u-boot-2009.11-rc1.2
由于当前uboot版本中没有mpc8308的gpio驱动,所以找了一下别的uboot版本,在uboot-2011-12中找到了
在/driver/gpio下找到mpc83xx_gpio.c,对比gpio的寄存器基地址和mpc8308的手册中gpio的地址 一致,说明驱动合适
说明一下,移植并不具有通用性,如果其他版本的uboot有相关芯片的定义也需要检查地址是否一致,如果没有可以仿照相关架构的芯片的驱动写一个
移植过程:
1.文件copy
将mpc8308xx_gpio.c copy到 u-boot-2009.11-rc1.2/drivers/gpio/下
并修改 Makefile
+COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o
我将mpc8308xx_gpio.c贴在最后
2.将涉及到的相关头文件内容添加到u-boot-2009.11-rc1.2/include 下
/* * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #ifndef _MPC83XX_GPIO_H_ #define _MPC83XX_GPIO_H_ /* * The MCP83xx's 1-2 GPIO controllers each with 32 bits. */ #if defined(CONFIG_MPC8313) || defined(CONFIG_MPC8308) || \ defined(CONFIG_MPC8315) #define MPC83XX_GPIO_CTRLRS 1 #elif defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) #define MPC83XX_GPIO_CTRLRS 2 #else #define MPC83XX_GPIO_CTRLRS 0 #endif #define MAX_NUM_GPIOS (32 * MPC83XX_GPIO_CTRLRS) void mpc83xx_gpio_init_f(void); void mpc83xx_gpio_init_r(void); #endif /* MPC83XX_GPIO_H_ */
3.添加gpio宏开关
在u-boot-2009.11-rc1.2/include/configs/MPC8308EDD.h 添加
+/*
+ *add 83xx gpio
+ */
+#define CONFIG_MPC83XX_GPIO
4.初始化
在/lib_ppc/board.c添加头文件
#include <gpio.h>
并在main_loop前添加初始化函数
mpc83xx_gpio_init_f();
mpc83xx_gpio_init_r();
mpc8308xx_gpio.c
/* * Freescale MPC83xx GPIO handling. * * See file CREDITS for list of people who contributed to this * project. * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <common.h> #include <mpc83xx.h> #include <asm/gpio.h> #include <asm/io.h> #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0 #endif #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0 #endif #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0 #endif #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0 #endif #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0 #endif #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0 #endif static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS]; /* * Generic_GPIO primitives. */ int gpio_request(unsigned gpio, const char *label) { if (gpio >= MAX_NUM_GPIOS) return -1; return 0; } int gpio_free(unsigned gpio) { /* Do not set to input */ return 0; } /* set GPIO pin 'gpio' as an input */ int gpio_direction_input(unsigned gpio) { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; unsigned int ctrlr; unsigned int line; unsigned int line_mask; /* 32-bits per controller */ ctrlr = gpio >> 5; line = gpio & (0x1F); /* Big endian */ line_mask = 1 << (31 - line); clrbits_be32(&im->gpio[ctrlr].dir, line_mask); return 0; } /* set GPIO pin 'gpio' as an output, with polarity 'value' */ int gpio_direction_output(unsigned gpio, int value) { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; unsigned int ctrlr; unsigned int line; unsigned int line_mask; if (value != 0 && value != 1) { printf("Error: Value parameter must be 0 or 1.\n"); return -1; } gpio_set_value(gpio, value); /* 32-bits per controller */ ctrlr = gpio >> 5; line = gpio & (0x1F); /* Big endian */ line_mask = 1 << (31 - line); /* Make the line output */ setbits_be32(&im->gpio[ctrlr].dir, line_mask); return 0; } /* read GPIO IN value of pin 'gpio' */ int gpio_get_value(unsigned gpio) { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; unsigned int ctrlr; unsigned int line; unsigned int line_mask; /* 32-bits per controller */ ctrlr = gpio >> 5; line = gpio & (0x1F); /* Big endian */ line_mask = 1 << (31 - line); /* Read the value and mask off the bit */ return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0; } /* write GPIO OUT value to pin 'gpio' */ int gpio_set_value(unsigned gpio, int value) { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; unsigned int ctrlr; unsigned int line; unsigned int line_mask; if (value != 0 && value != 1) { printf("Error: Value parameter must be 0 or 1.\n"); return -1; } /* 32-bits per controller */ ctrlr = gpio >> 5; line = gpio & (0x1F); /* Big endian */ line_mask = 1 << (31 - line); /* Update the local output buffer soft copy */ gpio_output_value[ctrlr] = (gpio_output_value[ctrlr] & ~line_mask) | \ (value ? line_mask : 0); /* Write the output */ out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]); return 0; } /* Configure GPIO registers early */ void mpc83xx_gpio_init_f() { immap_t *im = (immap_t *)CONFIG_SYS_IMMR; #if MPC83XX_GPIO_CTRLRS >= 1 out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION); out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN); out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE); out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */ out_be32(&im->gpio[0].imr, 0); out_be32(&im->gpio[0].icr, 0); #endif #if MPC83XX_GPIO_CTRLRS >= 2 out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION); out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN); out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE); out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */ out_be32(&im->gpio[1].imr, 0); out_be32(&im->gpio[1].icr, 0); #endif } /* Initialize GPIO soft-copies */ void mpc83xx_gpio_init_r() { #if MPC83XX_GPIO_CTRLRS >= 1 gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE; #endif #if MPC83XX_GPIO_CTRLRS >= 2 gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE; #endif }