mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
rk30:phonepad:support i2c transmission in sram
This commit is contained in:
@@ -19,6 +19,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_DVFS) += dvfs.o
|
||||
obj-$(CONFIG_DDR_FREQ) += ddr_freq.o
|
||||
obj-$(CONFIG_RK30_I2C_INSRAM) += i2c_sram.o
|
||||
|
||||
obj-$(CONFIG_MACH_RK3066_SDK) += board-rk30-sdk.o board-rk30-sdk-key.o
|
||||
obj-$(CONFIG_MACH_RK30_SDK) += board-rk30-sdk.o board-rk30-sdk-key.o
|
||||
|
||||
344
arch/arm/mach-rk30/i2c_sram.c
Executable file
344
arch/arm/mach-rk30/i2c_sram.c
Executable file
@@ -0,0 +1,344 @@
|
||||
#include <linux/io.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/sram.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/cru.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#define cru_readl(offset) readl_relaxed(RK30_CRU_BASE + offset)
|
||||
#define cru_writel(v, offset) do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0)
|
||||
|
||||
#if defined(CONFIG_RK30_I2C_INSRAM)
|
||||
|
||||
/******************need set when you use i2c*************************/
|
||||
#define I2C_SPEED 100
|
||||
#define I2C_SADDR (0x2D) /* slave address ,wm8310 addr is 0x34*/
|
||||
#define SRAM_I2C_CH 1 //CH==0, i2c0,CH==1, i2c1,CH==2, i2c2,CH==3, i2c3
|
||||
#define SRAM_I2C_ADDRBASE (RK30_I2C1_BASE + SZ_4K )//RK29_I2C0_BASE\RK29_I2C2_BASE\RK29_I2C3_BASE
|
||||
#define I2C_SLAVE_ADDR_LEN 1 // 2:slav addr is 10bit ,1:slav addr is 7bit
|
||||
#define I2C_SLAVE_REG_LEN 1 // 2:slav reg addr is 16 bit ,1:is 8 bit
|
||||
#define SRAM_I2C_DATA_BYTE 1 //i2c transmission data is 1bit(8wei) or 2bit(16wei)
|
||||
#define GRF_GPIO_IOMUX 0xd4 //GRF_GPIO2D_IOMUX
|
||||
/*ch=0:GRF_GPIO2L_IOMUX,ch=1:GRF_GPIO1L_IOMUX,ch=2:GRF_GPIO5H_IOMUX,ch=3:GRF_GPIO2L_IOMUX*/
|
||||
#define I2C_GRF_GPIO_IOMUX (0x01<<14)|(0x01<<12)
|
||||
/*CH=0:(~(0x03<<30))&(~(0x03<<28))|(0x01<<30)|(0x01<<28),CH=1:(~(0x03<<14))&(~(0x03<<12))|(0x01<<14)|(0x01<<12),
|
||||
CH=2:(~(0x03<<24))&(~(0x03<<22))|(0x01<<24)|(0x01<<22),CH=3:(~(0x03<<26))&(~(0x03<<24))|(0x02<<26)|(0x02<<24)*/
|
||||
/***************************************/
|
||||
|
||||
#define I2C_SLAVE_TYPE (((I2C_SLAVE_ADDR_LEN-1)<<4)|((I2C_SLAVE_REG_LEN-1)))
|
||||
|
||||
#define uint8 unsigned char
|
||||
#define uint16 unsigned short
|
||||
#define uint32 unsigned int
|
||||
uint32 __sramdata data[5];
|
||||
|
||||
#define CRU_CLKGATE0_CON 0xd0
|
||||
#define CRU_CLKGATE8_CON 0xf0
|
||||
#define CRU_CLKSEL1_CON 0x48
|
||||
#define GRF_GPIO5H_IOMUX 0x74
|
||||
#define GRF_GPIO2L_IOMUX 0x58
|
||||
#define GRF_GPIO1L_IOMUX 0x50
|
||||
|
||||
#define COMPLETE_READ (1<<STATE_START|1<<STATE_READ|1<<STATE_STOP)
|
||||
#define COMPLETE_WRITE (1<<STATE_START|1<<STATE_WRITE|1<<STATE_STOP)
|
||||
|
||||
/* Control register */
|
||||
#define I2C_CON 0x0000
|
||||
#define I2C_CON_EN (1 << 0)
|
||||
#define I2C_CON_MOD(mod) ((mod) << 1)
|
||||
#define I2C_CON_MASK (3 << 1)
|
||||
enum{
|
||||
I2C_CON_MOD_TX = 0,
|
||||
I2C_CON_MOD_TRX,
|
||||
I2C_CON_MOD_RX,
|
||||
I2C_CON_MOD_RRX,
|
||||
};
|
||||
#define I2C_CON_START (1 << 3)
|
||||
#define I2C_CON_STOP (1 << 4)
|
||||
#define I2C_CON_LASTACK (1 << 5)
|
||||
#define I2C_CON_ACTACK (1 << 6)
|
||||
|
||||
/* Clock dividor register */
|
||||
#define I2C_CLKDIV 0x0004
|
||||
#define I2C_CLKDIV_VAL(divl, divh) (((divl) & 0xffff) | (((divh) << 16) & 0xffff0000))
|
||||
#define rk30_ceil(x, y) \
|
||||
({ unsigned long __x = (x), __y = (y); (__x + __y - 1) / __y; })
|
||||
|
||||
/* the slave address accessed for master rx mode */
|
||||
#define I2C_MRXADDR 0x0008
|
||||
#define I2C_MRXADDR_LOW (1 << 24)
|
||||
#define I2C_MRXADDR_MID (1 << 25)
|
||||
#define I2C_MRXADDR_HIGH (1 << 26)
|
||||
|
||||
/* the slave register address accessed for master rx mode */
|
||||
#define I2C_MRXRADDR 0x000c
|
||||
#define I2C_MRXRADDR_LOW (1 << 24)
|
||||
#define I2C_MRXRADDR_MID (1 << 25)
|
||||
#define I2C_MRXRADDR_HIGH (1 << 26)
|
||||
|
||||
/* master tx count */
|
||||
#define I2C_MTXCNT 0x0010
|
||||
|
||||
/* master rx count */
|
||||
#define I2C_MRXCNT 0x0014
|
||||
|
||||
/* interrupt enable register */
|
||||
#define I2C_IEN 0x0018
|
||||
#define I2C_BTFIEN (1 << 0)
|
||||
#define I2C_BRFIEN (1 << 1)
|
||||
#define I2C_MBTFIEN (1 << 2)
|
||||
#define I2C_MBRFIEN (1 << 3)
|
||||
#define I2C_STARTIEN (1 << 4)
|
||||
#define I2C_STOPIEN (1 << 5)
|
||||
#define I2C_NAKRCVIEN (1 << 6)
|
||||
#define IRQ_MST_ENABLE (I2C_MBTFIEN | I2C_MBRFIEN | I2C_NAKRCVIEN | I2C_STARTIEN | I2C_STOPIEN)
|
||||
#define IRQ_ALL_DISABLE 0
|
||||
|
||||
/* interrupt pending register */
|
||||
#define I2C_IPD 0x001c
|
||||
#define I2C_BTFIPD (1 << 0)
|
||||
#define I2C_BRFIPD (1 << 1)
|
||||
#define I2C_MBTFIPD (1 << 2)
|
||||
#define I2C_MBRFIPD (1 << 3)
|
||||
#define I2C_STARTIPD (1 << 4)
|
||||
#define I2C_STOPIPD (1 << 5)
|
||||
#define I2C_NAKRCVIPD (1 << 6)
|
||||
#define I2C_IPD_ALL_CLEAN 0x7f
|
||||
|
||||
/* finished count */
|
||||
#define I2C_FCNT 0x0020
|
||||
|
||||
/* I2C tx data register */
|
||||
#define I2C_TXDATA_BASE 0X0100
|
||||
|
||||
/* I2C rx data register */
|
||||
#define I2C_RXDATA_BASE 0x0200
|
||||
|
||||
void __sramfunc sram_i2c_enable(void);
|
||||
void __sramfunc sram_i2c_disenable(void);
|
||||
|
||||
void __sramfunc sram_printch(char byte);
|
||||
void __sramfunc sram_printhex(unsigned int hex);
|
||||
|
||||
#define sram_udelay(usecs) SRAM_LOOP((usecs)*SRAM_LOOPS_PER_USEC)
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------
|
||||
Name : sram_i2c_init
|
||||
Desc : initialize the necessary registers
|
||||
Params : channel-determine which I2C bus we used
|
||||
Return : none
|
||||
------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void __sramfunc sram_i2c_init()
|
||||
{
|
||||
unsigned int div, divl, divh;
|
||||
//enable cru_clkgate8 clock
|
||||
data[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_CLKID(8)));
|
||||
|
||||
cru_writel(CLK_GATE_W_MSK(CLK_GATE_PCLK_I2C1)|CLK_UN_GATE(CLK_GATE_PCLK_I2C1),
|
||||
CLK_GATE_CLKID_CONS(CLK_GATE_PCLK_I2C1));
|
||||
|
||||
data[2] = readl_relaxed(RK30_GRF_BASE + GRF_GPIO_IOMUX);
|
||||
writel_relaxed(data[2]| I2C_GRF_GPIO_IOMUX, RK30_GRF_BASE + GRF_GPIO_IOMUX);
|
||||
|
||||
div = rk30_ceil(24*1000*1000, I2C_SPEED*1000 * 8);
|
||||
divh = divl = rk30_ceil(div, 2);
|
||||
writel_relaxed(I2C_CLKDIV_VAL(divl, divh), SRAM_I2C_ADDRBASE + I2C_CLKDIV);
|
||||
data[3] = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CLKDIV);
|
||||
sram_printhex(data[3]);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------
|
||||
Name : sram_i2c_deinit
|
||||
Desc : de-initialize the necessary registers
|
||||
Params : noe
|
||||
Return : none
|
||||
------------------------------------------------------------------------------------------------------*/
|
||||
void __sramfunc sram_i2c_deinit(void)
|
||||
{
|
||||
//restore iomux reg
|
||||
writel_relaxed(data[2], RK30_GRF_BASE + GRF_GPIO_IOMUX);
|
||||
|
||||
//restore scu clock reg
|
||||
cru_writel(data[1], CLK_GATE_CLKID_CONS(CLK_GATE_PCLK_I2C1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------
|
||||
Name : sram_i2c_start
|
||||
Desc : start i2c
|
||||
Params : none
|
||||
Return : none
|
||||
------------------------------------------------------------------------------------------------------*/
|
||||
void __sramfunc sram_i2c_read_enable(void)
|
||||
{
|
||||
writel_relaxed(((((I2C_CON_EN | I2C_CON_MOD(1)) | I2C_CON_LASTACK) )| I2C_CON_START) & (~(I2C_CON_STOP)) , SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
void __sramfunc sram_i2c_write_enable(void)
|
||||
{
|
||||
writel_relaxed(((((I2C_CON_EN | I2C_CON_MOD(0)) | I2C_CON_LASTACK) )| I2C_CON_START) & (~(I2C_CON_STOP)) , SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
|
||||
void __sramfunc sram_i2c_disenable(void)
|
||||
{
|
||||
writel_relaxed(0, SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
|
||||
void __sramfunc sram_i2c_clean_start(void)
|
||||
{
|
||||
unsigned int con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
|
||||
con = (con & (~I2C_CON_START)) ;
|
||||
writel_relaxed(con, SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
void __sramfunc sram_i2c_send_start(void)
|
||||
{
|
||||
unsigned int con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
con |= I2C_CON_START;
|
||||
if(con & I2C_CON_STOP)
|
||||
sram_printch('E');
|
||||
writel_relaxed(con, SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
void __sramfunc sram_i2c_send_stop(void)
|
||||
{
|
||||
unsigned int con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
con &= ~I2C_CON_START;
|
||||
con |= I2C_CON_STOP;
|
||||
if(con & I2C_CON_START)
|
||||
sram_printch('E');
|
||||
writel_relaxed(con, SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
void __sramfunc sram_i2c_clean_stop(void)
|
||||
{
|
||||
unsigned int con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
|
||||
con = (con & (~I2C_CON_STOP)) ;
|
||||
writel_relaxed(con, SRAM_I2C_ADDRBASE + I2C_CON);
|
||||
}
|
||||
|
||||
void __sramfunc sram_i2c_get_ipd_event(int type)
|
||||
{
|
||||
int time = 2000;
|
||||
unsigned int con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_IPD);
|
||||
writel_relaxed(type, SRAM_I2C_ADDRBASE + I2C_IEN);
|
||||
do{
|
||||
sram_udelay(10);
|
||||
con = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_IPD);
|
||||
}while(((--time) & (~(con & type))));
|
||||
writel_relaxed(type,SRAM_I2C_ADDRBASE + I2C_IPD);
|
||||
|
||||
if(time <= 0){
|
||||
sram_printch('T');
|
||||
}
|
||||
}
|
||||
|
||||
void __sramfunc sram_i2c_write_prepare(uint8 I2CSlaveAddr, uint8 regAddr,uint8 pdata)
|
||||
{
|
||||
u32 data = 0;
|
||||
unsigned int addr = (I2CSlaveAddr & 0x7f) << 1;
|
||||
|
||||
data = (addr | (regAddr << 8))|(pdata << 16);
|
||||
writel_relaxed(data , SRAM_I2C_ADDRBASE + I2C_TXDATA_BASE);
|
||||
writel_relaxed(3, SRAM_I2C_ADDRBASE + I2C_MTXCNT);
|
||||
}
|
||||
uint8 __sramfunc sram_i2c_read_prepare(uint8 I2CSlaveAddr, uint8 regAddr)
|
||||
{
|
||||
unsigned int addr = (I2CSlaveAddr & 0x7f) << 1;
|
||||
|
||||
writel_relaxed(addr | I2C_MRXADDR_LOW, SRAM_I2C_ADDRBASE + I2C_MRXADDR);
|
||||
writel_relaxed(regAddr | I2C_MRXADDR_LOW, SRAM_I2C_ADDRBASE + I2C_MRXRADDR);
|
||||
writel_relaxed(SRAM_I2C_DATA_BYTE, SRAM_I2C_ADDRBASE + I2C_MRXCNT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 __sramfunc sram_i2c_read_get_data(uint8 I2CSlaveAddr, uint8 regAddr)
|
||||
{
|
||||
unsigned int ret;
|
||||
ret = readl_relaxed(SRAM_I2C_ADDRBASE + I2C_RXDATA_BASE);
|
||||
ret = ret & 0x000000ff;
|
||||
return ret;
|
||||
|
||||
}
|
||||
uint8 __sramfunc sram_i2c_write(uint8 I2CSlaveAddr, uint8 regAddr,uint8 data)
|
||||
{
|
||||
sram_i2c_write_enable();
|
||||
sram_i2c_get_ipd_event(I2C_STARTIPD);
|
||||
sram_i2c_clean_start();
|
||||
|
||||
sram_i2c_write_prepare(I2CSlaveAddr,regAddr,data);
|
||||
sram_i2c_get_ipd_event(I2C_MBTFIPD);
|
||||
|
||||
sram_i2c_send_stop();
|
||||
sram_i2c_get_ipd_event(I2C_STOPIPD);
|
||||
sram_i2c_clean_stop();
|
||||
sram_i2c_disenable();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
uint8 __sramfunc sram_i2c_read(uint8 I2CSlaveAddr, uint8 regAddr)
|
||||
{
|
||||
unsigned int data;
|
||||
sram_i2c_read_enable();
|
||||
sram_i2c_get_ipd_event(I2C_STARTIPD);
|
||||
sram_i2c_clean_start();
|
||||
|
||||
sram_i2c_read_prepare(I2CSlaveAddr,regAddr);
|
||||
sram_i2c_get_ipd_event(I2C_MBRFIPD);
|
||||
|
||||
data = sram_i2c_read_get_data(I2CSlaveAddr,regAddr);
|
||||
|
||||
sram_i2c_send_stop();
|
||||
sram_i2c_get_ipd_event(I2C_STOPIPD);
|
||||
sram_i2c_clean_stop();
|
||||
sram_i2c_disenable();
|
||||
return data;
|
||||
}
|
||||
|
||||
void __sramfunc rk30_suspend_voltage_set(unsigned int vol)
|
||||
{
|
||||
uint8 slaveaddr;
|
||||
uint16 slavereg;
|
||||
uint8 data,ret;
|
||||
slaveaddr = I2C_SADDR; //slave device addr
|
||||
slavereg = 0x22; // reg addr
|
||||
data = 0x23; //set arm 1.0v
|
||||
|
||||
sram_i2c_init(); //init i2c device
|
||||
// ret = sram_i2c_read(slaveaddr, slavereg);
|
||||
// sram_printhex(ret);
|
||||
sram_i2c_write(slaveaddr, slavereg, data);//
|
||||
sram_i2c_deinit(); //deinit i2c device
|
||||
|
||||
}
|
||||
|
||||
void __sramfunc rk30_suspend_voltage_resume(unsigned int vol)
|
||||
{
|
||||
uint8 slaveaddr;
|
||||
uint16 slavereg;
|
||||
uint8 data,ret;
|
||||
slaveaddr = I2C_SADDR; //slave device addr
|
||||
slavereg = 0x22; // reg addr
|
||||
data = 0x2b;
|
||||
|
||||
sram_i2c_init(); //init i2c device
|
||||
// ret = sram_i2c_read(slaveaddr, slavereg);
|
||||
sram_i2c_write(slaveaddr, slavereg, data);
|
||||
sram_i2c_deinit(); //deinit i2c device
|
||||
}
|
||||
#else
|
||||
void __sramfunc rk30_suspend_voltage_set(unsigned int vol)
|
||||
{
|
||||
|
||||
}
|
||||
void __sramfunc rk30_suspend_voltage_resume(unsigned int vol)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
1
arch/arm/mach-rk30/include/mach/io.h
Normal file → Executable file
1
arch/arm/mach-rk30/include/mach/io.h
Normal file → Executable file
@@ -155,6 +155,7 @@
|
||||
#define RK30_I2C0_PHYS 0x2002c000
|
||||
#define RK30_I2C0_SIZE SZ_8K
|
||||
#define RK30_I2C1_PHYS 0x2002e000
|
||||
#define RK30_I2C1_BASE RK30_IO_TO_VIRT1(RK30_I2C1_PHYS)
|
||||
#define RK30_I2C1_SIZE SZ_8K
|
||||
#define RK30_PWM01_PHYS 0x20030000
|
||||
#define RK30_PWM01_BASE RK30_IO_TO_VIRT1(RK30_PWM01_PHYS)
|
||||
|
||||
2
arch/arm/mach-rk30/io.c
Normal file → Executable file
2
arch/arm/mach-rk30/io.c
Normal file → Executable file
@@ -55,6 +55,8 @@ static struct map_desc rk30_io_desc[] __initdata = {
|
||||
RK30_DEVICE(PWM23),
|
||||
RK30_DEVICE(DDR_PCTL),
|
||||
RK30_DEVICE(DDR_PUBL),
|
||||
RK30_DEVICE(I2C1),
|
||||
|
||||
#ifdef CONFIG_RK_SRAM_DMA
|
||||
{
|
||||
.virtual = (unsigned long) RK30_IMEM_NONCACHED,
|
||||
|
||||
15
arch/arm/mach-rk30/pm.c
Normal file → Executable file
15
arch/arm/mach-rk30/pm.c
Normal file → Executable file
@@ -261,7 +261,7 @@ static noinline void interface_ctr_reg_pread(void)
|
||||
readl_relaxed(RK30_GRF_BASE);
|
||||
readl_relaxed(RK30_DDR_PCTL_BASE);
|
||||
readl_relaxed(RK30_DDR_PUBL_BASE);
|
||||
|
||||
readl_relaxed(RK30_I2C1_BASE);
|
||||
}
|
||||
|
||||
static inline bool pm_pmu_power_domain_is_on(enum pmu_power_domain pd, u32 pmu_pwrdn_st)
|
||||
@@ -339,16 +339,22 @@ __weak void board_gpio_suspend(void) {}
|
||||
__weak void board_gpio_resume(void) {}
|
||||
__weak void __sramfunc board_pmu_suspend(void) {}
|
||||
__weak void __sramfunc board_pmu_resume(void) {}
|
||||
__weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol){}
|
||||
__weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol){}
|
||||
static void __sramfunc rk30_sram_suspend(void)
|
||||
{
|
||||
u32 cru_clksel0_con;
|
||||
u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
|
||||
u32 cru_mode_con;
|
||||
int i;
|
||||
|
||||
|
||||
sram_printch('5');
|
||||
ddr_suspend();
|
||||
sram_printch('6');
|
||||
rk30_suspend_voltage_set(1000000);
|
||||
sram_printch('7');
|
||||
|
||||
|
||||
for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
|
||||
clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
|
||||
}
|
||||
@@ -384,7 +390,7 @@ static void __sramfunc rk30_sram_suspend(void)
|
||||
| (1 << CLK_GATE_ACLK_INTMEM2 % 16)
|
||||
| (1 << CLK_GATE_ACLK_INTMEM3 % 16)
|
||||
, clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff);
|
||||
|
||||
|
||||
#ifdef CONFIG_CLK_SWITCH_TO_32K
|
||||
cru_mode_con = cru_readl(CRU_MODE_CON);
|
||||
cru_writel(0|
|
||||
@@ -413,9 +419,12 @@ static void __sramfunc rk30_sram_suspend(void)
|
||||
cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
|
||||
}
|
||||
|
||||
sram_printch('7');
|
||||
rk30_suspend_voltage_resume(1100000);
|
||||
sram_printch('6');
|
||||
ddr_resume();
|
||||
sram_printch('5');
|
||||
|
||||
}
|
||||
|
||||
static void noinline rk30_suspend(void)
|
||||
|
||||
@@ -111,6 +111,10 @@ menu "Support for RK power manage"
|
||||
config CLK_SWITCH_TO_32K
|
||||
bool "Support clock switch to 32.768k"
|
||||
|
||||
config RK30_I2C_INSRAM
|
||||
bool "Support i2c control interface in sram"
|
||||
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user