blob: 972413221b4a4ae9c036d79a5d526822cfcebdb7 [file] [log] [blame]
/*
* linux/arch/arm/mach-zx297510/gpio.c
*
* Copyright (C) 2013 ZTE-TSP
*
* 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.
*/
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/io.h>
#include <mach/iomap.h>
#include <mach/gpio.h>
#include <mach/debug.h>
#define AO_GPIO_1V8_IN_VA (ZX29_TOP_VA+0xC00)
#define AO_GPIO_1V8_OEN_VA (ZX29_TOP_VA+0xC04)
#define AO_GPIO_1V8_OUT_VA (ZX29_TOP_VA+0xC08)
#define AO_GPIO_1V8_SEL_VA (ZX29_TOP_VA+0x400)
#define ZX29_STB_GPIO_VA (ZX297510_STB_GPIO_BASE - ZX297510_A2APB_BASE + ZX29_A2APB_VA)
#define STB_GPIO_1V8_IN0_VA (ZX29_STB_GPIO_VA+0x800)
#define STB_GPIO_1V8_IN1_VA (ZX29_STB_GPIO_VA+0x804)
#define STB_GPIO_1V8_IN2_VA (ZX29_STB_GPIO_VA+0x808)
#define STB_GPIO_1V8_IN3_VA (ZX29_STB_GPIO_VA+0x80c)
#define STB_GPIO_1V8_OEN0_VA (ZX29_STB_GPIO_VA+0x810)
#define STB_GPIO_1V8_OEN1_VA (ZX29_STB_GPIO_VA+0x814)
#define STB_GPIO_1V8_OEN2_VA (ZX29_STB_GPIO_VA+0x818)
#define STB_GPIO_1V8_OEN3_VA (ZX29_STB_GPIO_VA+0x81c)
#define STB_GPIO_1V8_OUT0_VA (ZX29_STB_GPIO_VA+0x820)
#define STB_GPIO_1V8_OUT1_VA (ZX29_STB_GPIO_VA+0x824)
#define STB_GPIO_1V8_OUT2_VA (ZX29_STB_GPIO_VA+0x828)
#define STB_GPIO_1V8_OUT3_VA (ZX29_STB_GPIO_VA+0x82c)
#define STB_GPIO_1V8_SEL_VA (ZX29_TOP_VA+0x1000)
static void ao_gpio_sel(unsigned int pin_num, unsigned int value)
{
unsigned int tmp=0;
unsigned int offset=0;
if(pin_num<=1)
offset=0;
else{
if(pin_num>=6)
offset=7;
else
offset=4;
}
tmp = ioread32(AO_GPIO_1V8_SEL_VA+(pin_num+offset)*4);
tmp &= ~0x0f000000;
tmp |=(value&0xf)<<24;
iowrite32(tmp, AO_GPIO_1V8_SEL_VA+(pin_num+offset)*4);
}
static void stb_gpio_sel(unsigned int pin_num, unsigned int value)
{
unsigned int tmp=0;
unsigned int offset=0;
if((pin_num<=55)||((pin_num>=68)&&(pin_num<=95)))
offset=25;
else
if((pin_num>=56)&&(pin_num<=61))
offset=19;
else
if((pin_num>=62)&&(pin_num<=67))
offset=31;
else
if((pin_num>=97)&&(pin_num<=150))
offset=26;
else
ZDRV_ASSERT(0);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+(pin_num-offset)*4);
tmp &= ~0x0f000000;
tmp |=(value&0xf)<<24;
iowrite32(tmp, STB_GPIO_1V8_SEL_VA+(pin_num-offset)*4);
}
void zx29_gpio1v8_function_sel(unsigned int pin_num, unsigned int value)
{
if(pin_num<=24)
ao_gpio_sel(pin_num,value);
else
stb_gpio_sel(pin_num,value);
}
static unsigned int ao_gpio_sel_get(unsigned int pin_num)
{
unsigned int tmp=0;
unsigned int offset=0;
if(pin_num<=1)
offset=0;
else{
if(pin_num>=6)
offset=7;
else
offset=4;
}
tmp = ioread32(AO_GPIO_1V8_SEL_VA+(pin_num+offset)*4);
return tmp;
}
static unsigned int stb_gpio_sel_get(unsigned int pin_num)
{
unsigned int tmp=0;
unsigned int offset=0;
if((pin_num<=55)||((pin_num>=68)&&(pin_num<=95)))
offset=25;
else
if((pin_num>=56)&&(pin_num<=61))
offset=19;
else
if((pin_num>=62)&&(pin_num<=67))
offset=31;
else
if((pin_num>=97)&&(pin_num<=150))
offset=26;
else
ZDRV_ASSERT(0);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+(pin_num-offset)*4);
return tmp;
}
unsigned int zx29_gpio1v8_function_sel_get(unsigned int pin_num)
{
unsigned int tmp = 0;
if(pin_num<=24)
tmp = ao_gpio_sel_get(pin_num);
else
tmp = stb_gpio_sel_get(pin_num);
return tmp;
}
EXPORT_SYMBOL(zx29_gpio1v8_function_sel_get);
/*
*set always on area gpio pull-down and pull-up function
*/
static void ao_gpio_pd_pu_set(unsigned int pin_num, unsigned int type, unsigned int value)
{
unsigned int tmp=0;
unsigned int offset=0;
unsigned int shift=0;
if(pin_num<=1)
offset=0;
else{
if(pin_num>=6)
offset=7;
else
offset=4;
}
if(type)
shift=10;
else
shift=11;
tmp = ioread32(AO_GPIO_1V8_SEL_VA+(pin_num+offset)*4);
tmp &= ~(0x1<<shift);
tmp |=(value&0x1)<<shift;
iowrite32(tmp, AO_GPIO_1V8_SEL_VA+(pin_num+offset)*4);
}
/*
*set standby area gpio pull-down and pull-up function
*/
static void stb_gpio_pd_pu_set(unsigned int pin_num, unsigned int type, unsigned int value)
{
unsigned int tmp=0;
unsigned int offset=0;
unsigned int shift=0;
if((pin_num<=55)||((pin_num>=68)&&(pin_num<=95)))
offset=25;
else
if((pin_num>=56)&&(pin_num<=61))
offset=19;
else
if((pin_num>=62)&&(pin_num<=67))
offset=31;
else
if((pin_num>=97)&&(pin_num<=150))
offset=26;
else
ZDRV_ASSERT(0);
if(type)
shift=10;
else
shift=11;
tmp = ioread32(STB_GPIO_1V8_SEL_VA+(pin_num-offset)*4);
tmp &= ~(0x1<<shift);
tmp |=(value&0x1)<<shift;
iowrite32(tmp, STB_GPIO_1V8_SEL_VA+(pin_num-offset)*4);
}
/*
* set gpio resistance of pull-up and pull-down status
*@ pin_num: gpio pin number
*@ type: 0 pull-down 1 pull-up
*@ value: register value according to manual, only one bit
*/
void zx29_gpio1v8_pd_pu_set(unsigned int pin_num, unsigned int type,unsigned int value)
{
if(pin_num<=24)
ao_gpio_pd_pu_set(pin_num,type,value);
else
stb_gpio_pd_pu_set(pin_num,type,value);
}
/*
* enable pull-down resistance
*/
void zx29_gpio1v8_pd_enable(unsigned int pin_num)
{
zx29_gpio1v8_pd_pu_set(pin_num,0,1);
}
EXPORT_SYMBOL(zx29_gpio1v8_pd_enable);
/*
* disable pull-down resistance
*/
void zx29_gpio1v8_pd_disable(unsigned int pin_num)
{
zx29_gpio1v8_pd_pu_set(pin_num,0,0);
}
EXPORT_SYMBOL(zx29_gpio1v8_pd_disable);
/*
* enable pull-up resistance
*/
void zx29_gpio1v8_pu_enable(unsigned int pin_num)
{
zx29_gpio1v8_pd_pu_set(pin_num,1,1);
}
EXPORT_SYMBOL(zx29_gpio1v8_pu_enable);
/*
* disable pull-up resistance
*/
void zx29_gpio1v8_pu_disable(unsigned int pin_num)
{
zx29_gpio1v8_pd_pu_set(pin_num,1,0);
}
EXPORT_SYMBOL(zx29_gpio1v8_pu_disable);
void zx29_gpio1v8_set_direction(unsigned int pin_num, unsigned int value)
{
unsigned int bit_offset=pin_num%32;
unsigned int reg_index=pin_num/32;
unsigned int tmp=0;
void __iomem * reg_base=NULL;
if(pin_num<25){
reg_base=AO_GPIO_1V8_OEN_VA;
bit_offset=pin_num;
reg_index=0;
}
else{
if((pin_num<52)&&(pin_num>47)){
reg_base=AO_GPIO_1V8_OEN_VA;
bit_offset=pin_num-23;
reg_index=0;
}
else{
reg_base=STB_GPIO_1V8_OEN0_VA;
bit_offset=(pin_num-25)%32;
reg_index=(pin_num-25)/32;
}
}
tmp = ioread32(reg_base+reg_index*4);
/* value 0--output 1--input */
if (value)
{
tmp |= (1<<bit_offset);
}
else
{
tmp &= ~(1<<bit_offset);
}
iowrite32(tmp, reg_base+reg_index*4);
}
EXPORT_SYMBOL(zx29_gpio1v8_set_direction);
unsigned int zx29_gpio1v8_get_direction(unsigned int pin_num)
{
unsigned int bit_offset=pin_num%32;
unsigned int reg_index=pin_num/32;
unsigned int tmp=0;
void __iomem * reg_base=NULL;
if(pin_num<25){
reg_base=AO_GPIO_1V8_OEN_VA;
bit_offset=pin_num;
reg_index=0;
}
else{
if((pin_num<52)&&(pin_num>47)){
reg_base=AO_GPIO_1V8_OEN_VA;
bit_offset=pin_num-23;
reg_index=0;
}
else{
reg_base=STB_GPIO_1V8_OEN0_VA;
bit_offset=(pin_num-25)%32;
reg_index=(pin_num-25)/32;
}
}
tmp = ioread32(reg_base+reg_index*4);
/* value 0--output 1--input */
return ((tmp>>bit_offset)&0x1);
}
void zx29_gpio1v8_output_data(unsigned int pin_num, unsigned int value)
{
unsigned int bit_offset=0;
unsigned int reg_index=0;
unsigned int tmp=0;
void __iomem * reg_base=NULL;
if(pin_num<25){
reg_base=AO_GPIO_1V8_OUT_VA;
bit_offset=pin_num;
reg_index=0;
}
else{
if((pin_num<52)&&(pin_num>47)){
reg_base=AO_GPIO_1V8_OUT_VA;
bit_offset=pin_num-23;
reg_index=0;
}
else{
reg_base=STB_GPIO_1V8_OUT0_VA;
bit_offset=(pin_num-25)%32;
reg_index=(pin_num-25)/32;
}
}
tmp = ioread32(reg_base+reg_index*4);
if (value)
{
tmp |= (1<<bit_offset);
}
else
{
tmp &= ~(1<<bit_offset);
}
iowrite32(tmp, reg_base+reg_index*4);
}
EXPORT_SYMBOL(zx29_gpio1v8_output_data);
unsigned int zx29_gpio1v8_input_data(unsigned int pin_num)
{
unsigned int bit_offset=0;
unsigned int reg_index=0;
unsigned int tmp=0;
void __iomem * reg_base=NULL;
if(pin_num<25){
reg_base=AO_GPIO_1V8_IN_VA;
bit_offset=pin_num;
reg_index=0;
}
else{
if((pin_num<52)&&(pin_num>47)){
reg_base=AO_GPIO_1V8_IN_VA;
bit_offset=pin_num-23;
reg_index=0;
}
else{
reg_base=STB_GPIO_1V8_IN0_VA;
bit_offset=(pin_num-25)%32;
reg_index=(pin_num-25)/32;
}
}
tmp = ioread32(reg_base+reg_index*4);
tmp >>= bit_offset;
return (tmp&0x1);
}
EXPORT_SYMBOL(zx29_gpio1v8_input_data);
/*
* this function is used to config jtag mode
* jtag_num: jtag port ID
* function: jtag mode
*/
void jtag_config(unsigned int jtag_num, unsigned int function)
{
unsigned int tmp = 0;
if((jtag_num>2) || (function > 7)){
printk(KERN_INFO"jtag configuration error!\n");
return;
}
if (jtag_num == 0)
{
/*
*Jtag0
*0:M0Jtag, 1:function, 2:gpio, 3:psJtag, 4:phyJtag, 5:dspJtag, 6:ufiJtag, 7:gpio
*/
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x68);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x68);
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x6c);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x6c);
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x70);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x70);
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x74);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x74);
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x78);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x78);
tmp = ioread32(AO_GPIO_1V8_SEL_VA+0x7c);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,AO_GPIO_1V8_SEL_VA+0x7c);
}
else if (jtag_num == 1)
{
/*
*D0/Jtag1
*0:gpio, 1:sd0, 2:M0Jtag, 3:psJtag, 4:phyJtag, 5:dspJtag, 6:ufiJtag, 7:testpin
*/
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x7c);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x7c);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x80);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x80);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x84);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x84);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x88);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x88);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x8c);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x8c);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x90);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x90);
}
else if (jtag_num == 2)
{
/*
*SD1/Jtag2
*0:gpio, 1:sd1, 2:m0Jtag, 3:psJtag, 4:phyJtag, 5:dspJtag,6:gpio
*/
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x94);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x94);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x98);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x98);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0x9c);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0x9c);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0xa0);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0xa0);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0xa4);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0xa4);
tmp = ioread32(STB_GPIO_1V8_SEL_VA+0xa8);
tmp = (tmp&0xf0ffffff)|(function)<<24;
iowrite32(tmp,STB_GPIO_1V8_SEL_VA+0xa8);
}
printk(KERN_INFO"jtag%d config finished, function is %d!\n", jtag_num, function);
}
EXPORT_SYMBOL(jtag_config);