int UnmuteGF() { #ifdef _8925_8D1 //*(volatile unsigned int*)(gpa_vbase + OFFSET_PE) |= (0x1 << GPIO_NUM); //*(volatile unsigned int*)(gpa_vbase + OFFSET_PS) |= (0x1 << GPIO_NUM); *(volatile unsigned int*)(gpe_vbase + OFFSET_FUN2) &= ~(0xf << 4); *(volatile unsigned int*)(gpe_vbase + GPA_EN) |= (0x1 << GPION_MUTE); *(volatile unsigned int*)(gpe_vbase + GPA_DAT) |= (0x1 << GPION_MUTE); #else int file; file = i2copen(0); if( file == 0 ) return -1; i2cset(file,0x6c,0x0c,0x00,'b'); usleep( 35000 );//等 35 ms int nState = i2cget(file,0x6c,0x06,'b'); int nCount = 3; while( (nState != 0x0f) && (nCount-- > 0) ) { usleep( 35000 );//等 35 ms nState = i2cget(file,0x6c,0x06,'b'); fprintf(stderr, "UnmuteGF nState is %x, nCount is %d\n", nState, nCount); } i2cclose(file); #endif return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tps659038_is_present * @BRIEF return 1 if TPS659038 is present on this platform, * 0 otherwise * @RETURNS 1 if TPS659038 chip is found * 0 otherwise * @DESCRIPTION return 1 if TPS659038 is present on this platform, * 0 otherwise *//*------------------------------------------------------------------------ */ unsigned short int tps659038_is_present(void) { int ret; unsigned int id_lsb, id_msb; unsigned short present; switch (cpu_get()) { case DRA_7XX: ret = i2cget(TPS659038_I2C_BUS, TPS659038_ID1_ADDR, TPS659038_PRODUCT_ID_LSB, &id_lsb); if (ret != 0) return 0; ret = i2cget(TPS659038_I2C_BUS, TPS659038_ID1_ADDR, TPS659038_PRODUCT_ID_MSB, &id_msb); if (ret != 0) return 0; present = ((id_lsb == 0x35) && (id_msb == 0xc0)) ? 1 : 0; break; default: present = 0; } dprintf("%s(): present=%u\n", __func__, present); return present; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_is_twl6035 * @BRIEF return 1 if PMIC chip is TWL6035, 0 otherwise. * @RETURNS 1 PMIC chip is TWL6035 * 0 otherwise * @DESCRIPTION return 1 if PMIC chip is TWL6035, 0 otherwise. *//*------------------------------------------------------------------------ */ unsigned short twl603x_is_twl6035(void) { #if 0 /* FIXME: implement true detection when ID data available */ int ret; unsigned int val1, val2; if (twl603x_data.chip_type != TWL603X_TYPE_MAX) { dprintf("%s(): flag=%d\n", __func__, (twl603x_data.chip_type == TWL6035)); return twl603x_data.chip_type == TWL6035; } ret = i2cget(TWL6030_I2C_BUS, 0x49, 0x02, &val2); if (ret != 0) goto twl603x_is_twl6035_end; ret = i2cget(TWL6030_I2C_BUS, 0x49, 0x03, &val1); if (ret != 0) goto twl603x_is_twl6035_end; if ((val1 == 0xC0) && (val2 == 0x35)) twl603x_data.chip_type = TWL6035; twl603x_is_twl6035_end: dprintf("%s(): val1=0x%02X val2=0x%02X flag=%d\n", __func__, val1, val2, (twl603x_data.chip_type == TWL6035)); return twl603x_data.chip_type == TWL6035; #else /* FIXME: implement true detection when ID data available */ if (cpu_is_omap54xx()) return 1; else return 0; #endif }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_is_twl6034 * @BRIEF return 1 if PMIC chip is TWL6034, 0 otherwise. * @RETURNS 1 PMIC chip is TWL6034 * 0 otherwise * @DESCRIPTION return 1 if PMIC chip is TWL6034, 0 otherwise. *//*------------------------------------------------------------------------ */ unsigned short twl603x_is_twl6034(void) { int ret; unsigned int val1, val2; if (cpu_get() == DRA_75X) return 0; if (twl603x_data.chip_type != TWL603X_TYPE_MAX) { dprintf("%s(): flag=%d\n", __func__, (twl603x_data.chip_type == TWL6034)); return twl603x_data.chip_type == TWL6034; } ret = i2cget(TWL6030_I2C_BUS, 0x49, 0x02, &val2); if (ret != 0) goto twl603x_is_twl6034_end; ret = i2cget(TWL6030_I2C_BUS, 0x49, 0x03, &val1); if (ret != 0) goto twl603x_is_twl6034_end; if ((val1 == 0x00) && (val2 == 0x00)) twl603x_data.chip_type = TWL6034; twl603x_is_twl6034_end: dprintf("%s(): val1=0x%02X val2=0x%02X flag=%d\n", __func__, val1, val2, (twl603x_data.chip_type == TWL6034)); return twl603x_data.chip_type == TWL6034; }
/* ------------------------------------------------------------------------*//** * @FUNCTION main_i2c_read * @BRIEF read given data from given address of given device of * given I2C bus * @RETURNS 0 in case of success * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_REG_ACCESS * @param[in] argc: shell input argument number * argc must be 5 * @param[in] argv: shell input argument(s) * argv[2] = i2cbus: I2C bus number * argv[3] = address: I2C device address * argv[4] = daddress: I2C device register address * @DESCRIPTION read given data from given address of given device of * given I2C bus *//*------------------------------------------------------------------------ */ static int main_i2c_read(int argc, char *argv[]) { unsigned int i2cbus, chip_address, data_address; unsigned int data; int ret; CHECK_NULL_ARG(argv, OMAPCONF_ERR_ARG); /* Retrieve arguments */ if (argc != 5) goto main_i2c_read_err; ret = sscanf(argv[2], "%u", &i2cbus); if (ret != 1) goto main_i2c_read_err; ret = sscanf(argv[3], "0x%x", &chip_address); if (ret != 1) goto main_i2c_read_err; ret = sscanf(argv[4], "0x%x", &data_address); if (ret != 1) goto main_i2c_read_err; ret = i2cget(i2cbus, chip_address, data_address, &data); if (ret == 0) printf("0x%02x\n", data); return ret; main_i2c_read_err: printf( "Usage: omapconf i2c read 'i2cbus' 0x'chip-address' 0x'data-address'\n"); printf(" 'i2cbus' is decimal value.\n"); printf(" 'chip-address' & 'data-address' are hexadecimal values.\n"); printf(" Warning: prefix '0x' is mandatory.\n"); return OMAPCONF_ERR_ARG; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tps65217x_chip_revision_get * @BRIEF return TPS65217X chip revision * @RETURNS > 0.0 TPS65217X chip revision * OMAPCONF_ERR_UNEXPECTED in case of error * @DESCRIPTION return TPS65217X chip revision *//*------------------------------------------------------------------------ */ double tps65217x_chip_revision_get(void) { int ret; unsigned int rev; if (chip_revision > 0) goto tps65217x_chip_revision_get_end; ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, 0x00, &rev); if (ret != 0) { fprintf(stderr, "%s(): could not read register! (%d)\n", __func__, ret); chip_revision = (float) OMAPCONF_ERR_NOT_AVAILABLE; goto tps65217x_chip_revision_get_end; } dprintf("%s(): rev=%02X\n", __func__, rev); switch (rev & 0xF) { case 0x0: chip_revision = 1.0; break; case 0x01: chip_revision = 1.1; break; case 0x02: chip_revision = 1.2; break; default: chip_revision = (float) OMAPCONF_ERR_UNEXPECTED; } tps65217x_chip_revision_get_end: dprintf("%s(): chip_revision = %f\n", __func__, chip_revision); return chip_revision; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tps65217x_is_present * @BRIEF return 1 if TPS65217X is present on this platform, * 0 otherwise * @RETURNS 1 if TPS65217X chip is found * 0 otherwise * @DESCRIPTION return 1 if TPS65217X is present on this platform, * 0 otherwise *//*------------------------------------------------------------------------ */ unsigned short int tps65217x_is_present(void) { int ret; unsigned int id_lsb; unsigned short present; switch (cpu_get()) { case AM_3352: case AM_3354: case AM_3356: case AM_3357: case AM_3358: case AM_3359: /* Check to see if address is readable */ ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, 0x00, &id_lsb); if (ret != 0) return 0; /* Check to see if chip and revision is valid */ present = ((tps65217x_chip_get() >= 6) || tps65217x_chip_revision_get() > 0) ? 1 : 0; break; default: present = 0; } dprintf("%s(): present=%u\n", __func__, present); return present; }
int Incar_AirconditionGet(structAirInfo*test) { int error = 0; unsigned char buf[6]; if( !test ) return -1; if( i2c < 0 ) { openi2c(); if( i2c < 0 ) error = -2; } if( !error ) { buf[0] = 0x0a; int try1 = 2; while(try1 --) { i2cset(i2c,0x50,buf,1); i2cget(i2c,0x50,buf,6); int i; i = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5] ; i = i & 0x7f; if(((buf[5]>>7)==0) && (i==0x7a)) break; } if( try1 <= 0 ) error = -3; }
int DetectGF() { #ifndef _8925_8D1 int file; file = i2copen(0); if(file == 0) return -1; int nState1 = i2cget(file,0x6c,0x00,'b'); int nState2 = i2cget(file,0x6c,0x01,'b'); if( nState1 != 0x00 || nState2 != 0x00 ) { UnmuteGF(); } i2cclose(file); #endif return 0; }
int Incar_brightnessGet() { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } return i2cget(i2c,0x45,0x74,'b'); }
int Incar_ContrastGet() { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } return i2cget(i2c,0x45,0x71,'b'); }
int Incar_backclothGet() { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } return i2cget(i2c,0x45,0xc4,'b') ; }
int InitGF() { #ifndef _8925_8D1 int file,i; file = i2copen(0); if( file == 0 ) return -1; Incar_initvolume(); //把声音设置为工作状态 i2cset( file, 0x50, 0x00, 0xFF, 'b' ); //必须进行延时,等待功放稳定,否则配置无效 usleep( 200000 ); //必须读0x00 和0x01地址,清除失败状态 i2cget(file,0x6c,0x00,'b'); i2cget(file,0x6c,0x01,'b'); //以下功能检查是否输出短路 i2cset( file, 0x50, 0x0b, 0x0F, 'b' ); usleep( 200000 );//等 200 ms int nCount = 10; int nState = i2cget(file,0x6c,0x07,'b'); while( (nState != 0x00) && (nCount-- > 0)) { usleep( 35000 );//等 35 ms nState = i2cget(file,0x6c,0x07,'b'); fprintf(stderr, "InitGF nState is %x, nCount is %d\n", nState, nCount); } int nState1 = i2cget(file,0x6c,0x02,'b'); int nState2 = i2cget(file,0x6c,0x03,'b'); if( nState1 != 0x00 || nState2 != 0x00 ) { printf("tas5414_master 0x02 0x03 address is %x %x\n", nState1, nState2); return -2; } //写用户配置参数 unsigned char* p = tas5414_master; for(i = 0;i < (int)(sizeof(tas5414_master)/sizeof(tas5414_master[0]));i+=2) { i2cset(file,0x6c,*p,*(p+1),'b'); p += 2; } i2cclose(file); usleep( 3000000 );//必须进行延时,等待功放稳定,否则立即切换界面不能屏蔽电流冲击声 #endif return 0; }
int Incar_ContrastSet(int value) { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } int i; i = i2cget(i2c,0x45,0x70,'b'); i = i | 0x40; i2cset(i2c,0x45,0x70,i,'b'); i2cset(i2c,0x45,0x71,value,'b'); i2cset(i2c,0x45,0x72,value,'b'); i2cset(i2c,0x45,0x73,value,'b'); return 0; }
int Incar_brightnessSet(int value) { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } int i; i = i2cget(i2c,0x45,0x70,'b'); i = i | 0x40; i2cset(i2c,0x45,0x70,i,'b'); i2cset(i2c,0x45,0x74,value,'b'); i2cset(i2c,0x45,0x75,value,'b'); i2cset(i2c,0x45,0x76,value,'b'); return 0; }
int Incar_PowerEnable( int device , int enable ) { if( i2c < 0 ) { openi2c(); if( i2c < 0 ) return -1; } if( device >= Incar_Power_Gps && device <= Incar_Power_Dvd ) { int value = i2cget( i2c , MCUADDR , addr_POWER_read , 'b' ); if( enable ) value |= 1<<(device+1); else value &= ~(1<<(device+1)); return i2cset( i2c , MCUADDR , addr_POWER_write , value , 'b' ); } else return -1; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_chip_revision_get * @BRIEF return TWL6030 chip revision * @RETURNS > 0.0 valid TWL6030 chip revision * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_UNEXPECTED * @DESCRIPTION return TWL6030 chip revision *//*------------------------------------------------------------------------ */ float twl603x_chip_revision_get(void) { int ret; unsigned int rev; if (twl603x_data.chip_revision > 0) goto twl603x_chip_revision_get_end; ret = i2cget(TWL6030_I2C_BUS, 0x4A, 0x87, &rev); if (ret != 0) { fprintf(stderr, "%s(): could not read register! (%d)\n", __func__, ret); twl603x_data.chip_revision = (float) OMAPCONF_ERR_NOT_AVAILABLE; goto twl603x_chip_revision_get_end; } dprintf("%s(): rev=%u\n", __func__, rev); switch (rev) { case 0x0: twl603x_data.chip_revision = 1.0; break; case 0x01: if (twl603x_data.chip_type == TWL6032) twl603x_data.chip_revision = 1.1; else twl603x_data.chip_revision = 2.0; break; case 0x02: twl603x_data.chip_revision = 2.1; break; default: twl603x_data.chip_revision = (float) OMAPCONF_ERR_UNEXPECTED; } twl603x_chip_revision_get_end: dprintf("%s(): chip_revision = %f\n", __func__, twl603x_data.chip_revision); return twl603x_data.chip_revision; }
int PowerOffGF() { #ifndef _8925_8D1 int file; file = i2copen(0); if( file == 0 ) return -1; //由PLAY-MODE进入到MUTE-MODE i2cset(file,0x6c,0x0c,0x10,'b'); int nCount = 10; int nState = i2cget(file,0x6c,0x06,'b'); while( (nState != 0xf0) && (nCount-- > 0) ) { usleep( 35000 );//等 35 ms nState = i2cget(file,0x6c,0x06,'b'); fprintf(stderr, "PowerOffGF MUTE-MODE i2cget 0x6c,0x06 nState is %x, nCount is %d\n", nState, nCount); } //由MUTE-MODE 进入到LOW-LOW-MODE i2cset(file,0x6c,0x0d,0x0f,'b'); nCount = 10; nState = i2cget(file,0x6c,0x05,'b'); while( (nState != 0xf0) && (nCount-- > 0) ) { usleep( 35000 );//等 35 ms nState = i2cget(file,0x6c,0x05,'b'); fprintf(stderr, "PowerOffGF LOW-LOW-MODE i2cget 0x6c,0x05 nState is %x, nCount is %d\n", nState, nCount); } //由LOW-LOW-MODE 进入到HIZ-MODE i2cset(file,0x6c,0x0c,0x1f,'b'); nCount = 10; nState = i2cget(file,0x6c,0x05,'b'); while( (nState != 0x0f) && (nCount-- > 0) ) { usleep( 35000 );//等 35 ms nState = i2cget(file,0x6c,0x05,'b'); fprintf(stderr, "PowerOffGF HIZ-MODE i2cget 0x6c,0x05 nState is %x, nCount is %d\n", nState, nCount); } i2cclose(file); #endif return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tps65217x_chip_get * @BRIEF return TPS65217X chip * @RETURNS > 0.0 TPS65217X chip * OMAPCONF_ERR_UNEXPECTED in case of error * @DESCRIPTION return TPS65217X chip (A, B, C, D, UNKNOWN) *//*------------------------------------------------------------------------ */ int tps65217x_chip_get(void) { int ret; unsigned int rev; unsigned short int pmic_chip; ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, 0x00, &rev); if (ret != 0) { fprintf(stderr, "%s(): could not read register! (%d)\n", __func__, ret); pmic_chip = OMAPCONF_ERR_NOT_AVAILABLE; goto tps65217x_chip_get_end; } dprintf("%s(): rev=%02x\n", __func__, rev); switch (rev & 0xF0) { case 0x60: pmic_chip = 9; /* TPS65217D */ break; case 0x70: pmic_chip = 6; /* TPS65217A */ break; case 0xE0: pmic_chip = 8; /* TPS65217C */ break; case 0xF0: pmic_chip = 7; /* TPS65217B */ break; default: pmic_chip = OMAPCONF_ERR_UNEXPECTED; } tps65217x_chip_get_end: dprintf("%s(): pmic_chip = %d %d\n", __func__, pmic_chip, chip_type); chip_type = pmic_chip; return pmic_chip; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_eprom_revision_get * @BRIEF return TWL603x EPROM revision * @RETURNS >0 .0 valid TWL6030 EPROM revision * OMAPCONF_ERR_NOT_AVAILABLE * @DESCRIPTION return TWL603x EPROM revision *//*------------------------------------------------------------------------ */ float twl603x_eprom_revision_get(void) { int ret; unsigned int rev; if (twl603x_data.eprom_revision > 0) goto twl603x_eprom_revision_get_end; ret = i2cget(TWL6030_I2C_BUS, 0x4A, 0xDF, &rev); if (ret != 0) { fprintf(stderr, "%s(): could not read register! (%d)\n", __func__, ret); twl603x_data.eprom_revision = (float) OMAPCONF_ERR_NOT_AVAILABLE; goto twl603x_eprom_revision_get_end; } dprintf("%s(): rev=%u\n", __func__, rev); twl603x_data.eprom_revision = (float) (rev); twl603x_eprom_revision_get_end: dprintf("%s(): eprom_revision = %f\n", __func__, twl603x_data.eprom_revision); return twl603x_data.eprom_revision; }
int main(int argc, char *argv[]) { int i2cbus, address, daddress; short x_val, y_val, z_val; if(argc < 2) { fprintf(stderr, "Usage: %s <i2c-bus> <i2c-address>\n", argv[0]); exit(1); } i2cbus = atoi(argv[1]); address = atoi(argv[2]); //continuously read and print the values for each axis while(1){ //set to continuous measurement mode i2cset(i2cbus, address, 2, 0); x_val = ((i2cget(i2cbus, address, 3) << 8) + i2cget(i2cbus, address, 4)); //small wait usleep(50000); z_val = ((i2cget(i2cbus, address, 5) << 8) + i2cget(i2cbus, address, 6)); //small wait usleep(50000); y_val = ((i2cget(i2cbus, address, 7) << 8) + i2cget(i2cbus, address, 8)); fprintf(stderr, "x value = %d, y value = %d, z value = %d\r", x_val, y_val, z_val); //small wait usleep(50000); } return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tlv320aic3x_dumpregs * @BRIEF dump registers from table given as argument * @RETURNS 0 in case of success * OMAPCONF_ERR_REG_ACCESS * @param[in] none * @DESCRIPTION dump registers from table given as argument *//*------------------------------------------------------------------------ */ int tlv320aic3x_dumpregs(int argc, char *argv[]) { unsigned int i = 0; unsigned int val = 0; int ret, err = 0; char autoadjust_table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row; unsigned int i2cbus, chip_address; if (argc == 1) { /* Take defaults: bus 0, address 0x18 */ i2cbus = 0; chip_address = TLV320AIC3X_I2C_VALID_ADDR1; } else if (argc == 3) { if (argv == NULL) { printf("%s(): argv == NULL!!!\n", __func__); return OMAPCONF_ERR_ARG; } ret = sscanf(argv[1], "%u", &i2cbus); if (ret != 1) { tlv320aic3x_dumpregs_usage(); return OMAPCONF_ERR_ARG; } ret = sscanf(argv[2], "0x%x", &chip_address); if (ret != 1) { tlv320aic3x_dumpregs_usage(); return OMAPCONF_ERR_ARG; } } switch (chip_address) { case TLV320AIC3X_I2C_VALID_ADDR1: case TLV320AIC3X_I2C_VALID_ADDR2: case TLV320AIC3X_I2C_VALID_ADDR3: case TLV320AIC3X_I2C_VALID_ADDR4: break; default: printf("Invalid chip address, valid addresses are: 0x%02x - 0x%02x\n", TLV320AIC3X_I2C_VALID_ADDR1, TLV320AIC3X_I2C_VALID_ADDR4); return OMAPCONF_ERR_NOT_AVAILABLE; } /* Read register 0 (Page select) to see if other i2c reads can succeed */ ret = i2cget(i2cbus, chip_address, tlv320aic3x_reg_table[i].addr, &val); if (ret) { printf("I2C chip is not accessible\n"); return OMAPCONF_ERR_REG_ACCESS; } autoadjust_table_init(autoadjust_table); row = 0; printf("I2C bus: %u\n", i2cbus); printf("Chip address: 0x%02x\n\n", chip_address); strncpy(autoadjust_table[row][0], "Reg. Name", TABLE_MAX_ELT_LEN); strncpy(autoadjust_table[row][1], "Reg. Addr", TABLE_MAX_ELT_LEN); strncpy(autoadjust_table[row][2], "Reg. Val.", TABLE_MAX_ELT_LEN); row++; while (strcmp(tlv320aic3x_reg_table[i].name, "END") != 0) { ret = i2cget(i2cbus, chip_address, tlv320aic3x_reg_table[i].addr, &val); if (ret == 0) { /* Show register name, addr & content (hex) */ snprintf(autoadjust_table[row][0], TABLE_MAX_ELT_LEN, "%s", tlv320aic3x_reg_table[i].name); snprintf(autoadjust_table[row][1], TABLE_MAX_ELT_LEN, "%3u", tlv320aic3x_reg_table[i].addr); snprintf(autoadjust_table[row][2], TABLE_MAX_ELT_LEN, "0x%02X", val); row++; } else if (ret == -4) { /* * Some registers maybe unaccessible if * its voltage domain is disabled */ snprintf(autoadjust_table[row][0], TABLE_MAX_ELT_LEN, "%s", tlv320aic3x_reg_table[i].name); snprintf(autoadjust_table[row][1], TABLE_MAX_ELT_LEN, "%3u", tlv320aic3x_reg_table[i].addr); snprintf(autoadjust_table[row][2], TABLE_MAX_ELT_LEN, "INACTIVE"); row++; } else { printf("omapconf_tlv320aic3x_dumpregs(): read error! " "(addr=%u, err=%d)\n", tlv320aic3x_reg_table[i].addr, ret); err = OMAPCONF_ERR_REG_ACCESS; break; } i++; } autoadjust_table_print(autoadjust_table, row, 3); return err; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tps65217x_vsel_get * @BRIEF return vsel-encoded voltage of a given SMPS voltage rail * @RETURNS VSEL-encoded voltage (8-bit, >= 0) in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_REG_ACCESS * OMAPCONF_ERR_INTERNAL * @param[in] smps_id: voltage domain ID * @DESCRIPTION return vsel-encoded voltage of a given SMPS voltage rail *//*------------------------------------------------------------------------ */ int tps65217x_vsel_get(unsigned int smps_id) { int ret; unsigned int val, vsel, stat_bit; const tps65217x_smps_registers **vdd_smps_regs; const tps65217x_smps_registers *smps_regs; CHECK_ARG_LESS_THAN(smps_id, 5, OMAPCONF_ERR_ARG); /* Retrive SMPS registers addresses */ vdd_smps_regs = tps65217x_smps_vdd_am335x[smps_id]; if (vdd_smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; smps_regs = *vdd_smps_regs; if (smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; dprintf("%s(): smps_id=%u ADDR: ctrl=0x%02X tstep=0x%02X " "voltage=0x%02X\n", __func__, smps_id, smps_regs->ctrl, smps_regs->tstep, smps_regs->voltage); /* Check SMPS Status */ if (smps_regs->ctrl == -1) { dprintf("%s(): SMPSxx_CTRL addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, smps_regs->ctrl, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; /* MPU and CORE share same enable register */ switch (chip_type) { case 6: /* * TPS65217A is for AM335X ZCE package * MPU and CORE are combined for this package */ stat_bit = 3; break; case 7: if (smps_id == 0) stat_bit = 4; else stat_bit = 3; break; case 8: case 9: if (smps_id == 0) stat_bit = 3; else stat_bit = 4; break; default: fprintf(stderr, "%s(): should not reach here?!\n", __func__); return OMAPCONF_ERR_INTERNAL; } dprintf("%s(): SMPSxx_CTRL=0x%02X\n", __func__, val); if (extract_bit(val, stat_bit) == 0) { dprintf("(%s(): warning SMPS is OFF\n", __func__); return 0; } /* Check SMPS voltage controlled by registers, not resource pins */ ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, smps_regs->voltage, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; if (extract_bit(val, 7) == 1) { dprintf("%s(): SMPS voltage controlled by resource pins\n", __func__); return OMAPCONF_ERR_NOT_AVAILABLE; } /* Retrieve VSEL (6-bits) from relevant register */ if (smps_regs->voltage != -1) { ret = i2cget(TPS65217X_I2C_BUS, TPS65217X_ID0_ADDR, smps_regs->voltage, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPSxx_VOLTAGE=0x%02X\n", __func__, val); } else { dprintf("%s(): SMPSxx_VOLTAGE addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } vsel = extract_bitfield(val, 0, TPS65217X_VSEL_LEN); dprintf("%s(): SMPSxx_VOLTAGE=0x%02X SMPSxx_VOLTAGE.VSEL=0x%02X\n", __func__, val, vsel); return vsel; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_uvoltage_set * @BRIEF set voltage of a given SMPS voltage rail. * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_REG_ACCESS * OMAPCONF_ERR_INTERNAL * @param[in] vdd_id: voltage domain ID * @param[in] uv: voltage to be set (in micro-volt) * @DESCRIPTION set voltage of a given SMPS voltage rail, in micro-volt. * NB: not supported by TWL6030/TWL6032. *//*------------------------------------------------------------------------ */ int twl603x_uvoltage_set(unsigned int vdd_id, unsigned long uv) { int ret; unsigned int val; unsigned char vsel; const twl6035_smps_registers **vdd_smps_regs; const twl6035_smps_registers *smps_regs; if (!twl603x_is_twl6035()) return OMAPCONF_ERR_CPU; CHECK_ARG_LESS_THAN(vdd_id, 3, OMAPCONF_ERR_ARG); /* Retrive SMPS registers addresses */ vdd_smps_regs = twl6035_smps_vdd54xx[vdd_id]; if (vdd_smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; smps_regs = *vdd_smps_regs; if (smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; dprintf("%s(): vdd_id=%u ADDR: ctrl=0x%02X tstep=0x%02X force=0x%02X " "voltage=0x%02X\n", __func__, vdd_id, smps_regs->ctrl, smps_regs->tstep, smps_regs->force, smps_regs->voltage); /* Check SMPS Status */ /* FIXME: create dedicated API */ if (smps_regs->ctrl == -1) { dprintf("%s(): SMPSxx_CTRL addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } ret = i2cget(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->ctrl, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPSxx_CTRL=0x%02X\n", __func__, val); if (extract_bitfield(val, 4, 2) == 0) { dprintf("(%s(): SMPS is OFF\n", __func__); return OMAPCONF_ERR_NOT_AVAILABLE; } /* Make sure SMPSxx_CTRL.ROOF_FLOOR_EN=0 */ /* FIXME: create dedicated API */ if (extract_bit(val, 6) == 1) { dprintf("%s(): SMPS voltage controlled by resource pins, " "clearing ROOF_FLOOR_EN bit.\n", __func__); /* Clear ROOF_FLOOR_EN bit (6) */ val = val & 0xBF; ret = i2cset(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->ctrl, (unsigned int) val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPS voltage now controlled by " "SMPS12_FORCE.CMD bit.\n", __func__); } else { dprintf("%s(): SMPS voltage controlled by " "SMPS12_FORCE.CMD bit.\n", __func__); } /* Convert voltage to VSEL */ vsel = twl603x_uv_to_vsel(vdd_id, uv); dprintf("%s(): uv=%lu vsel=0x%02X\n", __func__, uv, vsel); /* Write VSEL to SMPSxx_VOLTAGE */ ret = i2cset(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->voltage, (unsigned int) vsel); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; /* * Try to switch voltage control to SMPSxx_FORCE register (if exists) * so that voltage will not be overriden by kernel during * DVFS, AVS or power transition. */ if (smps_regs->force != -1) { dprintf("%s(): SMPSxx_FORCE exists, switching control.\n", __func__); /* Clear bit 7 (CMD) */ val = vsel & 0x7F; ret = i2cset(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->force, (unsigned int) val); } else { dprintf("%s(): SMPSxx_FORCE does not exist.\n", __func__); ret = 0; } return ret; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_vsel_get * @BRIEF return vsel-encoded voltage of a given SMPS voltage rail * @RETURNS VSEL-encoded voltage (8-bit, >= 0) in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_REG_ACCESS * OMAPCONF_ERR_INTERNAL * @param[in] vdd_id: voltage domain ID * @DESCRIPTION return vsel-encoded voltage of a given SMPS voltage rail * NB: not supported by TWL6030/TWL6032. *//*------------------------------------------------------------------------ */ int twl603x_vsel_get(unsigned int vdd_id) { int ret; unsigned int val, vsel_addr, vsel, range; const twl6035_smps_registers **vdd_smps_regs; const twl6035_smps_registers *smps_regs; if (!twl603x_is_twl6035()) return OMAPCONF_ERR_CPU; CHECK_ARG_LESS_THAN(vdd_id, 3, OMAPCONF_ERR_ARG); /* Retrive SMPS registers addresses */ vdd_smps_regs = twl6035_smps_vdd54xx[vdd_id]; if (vdd_smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; smps_regs = *vdd_smps_regs; if (smps_regs == NULL) return OMAPCONF_ERR_INTERNAL; dprintf("%s(): vdd_id=%u ADDR: ctrl=0x%02X tstep=0x%02X force=0x%02X " "voltage=0x%02X\n", __func__, vdd_id, smps_regs->ctrl, smps_regs->tstep, smps_regs->force, smps_regs->voltage); /* Check SMPS Status */ /* FIXME: create dedicated API */ if (smps_regs->ctrl == -1) { dprintf("%s(): SMPSxx_CTRL addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } ret = i2cget(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->ctrl, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPSxx_CTRL=0x%02X\n", __func__, val); if (extract_bitfield(val, 4, 2) == 0) { dprintf("(%s(): warning SMPS is OFF\n", __func__); return 0; } /* Check SMPS voltage controlled by registers, not resource pins */ /* FIXME: create dedicated API */ if (extract_bit(val, 6) == 1) { dprintf("%s(): SMPS voltage controlled by resource pins\n", __func__); return OMAPCONF_ERR_NOT_AVAILABLE; } /* * Retrieve if voltage is controlled via * SMPSxx_FORCE.VSEL or SMPSxx_VOLTAGE.VSEL */ if (smps_regs->force == -1) { dprintf("%s(): SMPSxx_FORCE register does not exist, " "use SMPSxx_VOLTAGE register.\n", __func__); vsel_addr = smps_regs->voltage; } else { ret = i2cget(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->force, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPSxx_FORCE=0x%02X\n", __func__, val); if (extract_bit(val, 7) == 1) { dprintf("%s(): CMD=1 => use SMPSxx_VOLTAGE register.\n", __func__); vsel_addr = smps_regs->voltage; } else { dprintf("%s(): CMD=0 => use SMPSxx_FORCE register.\n", __func__); vsel_addr = smps_regs->force; } } /* Retrieve VSEL (7-bit LSB) from relevant register */ if (vsel_addr == (unsigned int) smps_regs->voltage) { if (smps_regs->voltage == -1) { dprintf("%s(): SMPSxx_VOLTAGE addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } ret = i2cget(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->voltage, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; dprintf("%s(): SMPSxx_VOLTAGE=0x%02X\n", __func__, val); } vsel = extract_bitfield(val, 0, 7); dprintf("%s(): SMPSxx_VOLTAGE=0x%02X SMPSxx_VOLTAGE.VSEL=0x%02X\n", __func__, val, vsel); /* Retrieve VSEL range from SMPSxx_VOLTAGE register (bit 7) */ if (vsel_addr != (unsigned int) smps_regs->voltage) { if (smps_regs->voltage == -1) { dprintf("%s(): SMPSxx_VOLTAGE addr=-1!!!\n", __func__); return OMAPCONF_ERR_INTERNAL; } ret = i2cget(TWL6035_I2C_BUS, TWL6035_ID1_ADDR, smps_regs->voltage, &val); if (ret != 0) return OMAPCONF_ERR_REG_ACCESS; } range = extract_bit(val, 7); dprintf("%s(): SMPSxx_VOLTAGE=0x%02X SMPSxx_VOLTAGE.RANGE=%u\n", __func__, val, range); /* Return VSEL (7-bit LSB), including range (MSB) */ vsel = vsel | (range << 7); dprintf("%s(): vsel=0x%02X\n", __func__, vsel); return vsel; }
/* ------------------------------------------------------------------------*//** * @FUNCTION twl603x_smps_offset_get * @BRIEF return SMPS regulator offset for a given rail * @RETURNS >0 voltage offset in microvolts * OMAPCONF_ERR_NOT_AVAILABLE * @param[in] vdd_id: voltage rail * @DESCRIPTION return SMPS regulator offset for a given rail *//*------------------------------------------------------------------------ */ unsigned long twl603x_smps_offset_get(voltdm44xx_id vdd_id) { int ret; unsigned int val; char product_name[256]; if (twl603x_is_twl6035()) return TWL6035_VOFFSET_UV; if (twl603x_data.voffset[vdd_id - 1] >= 0) goto twl603x_smps_offset_get_end; /* * TWL6030: * Starting ES2.x, Phoenix PMIC may use 709mV offset instead of 608mV * depending on setting: OFFSET=1: 709mV, OFFSET=0: 608mV. */ if (twl603x_is_twl6030() && twl603x_chip_revision_get() == 1.0) { dprintf("%s(%u): TWL60ES1 => TWL6030_VOFFSET_0_UV\n", __func__, vdd_id); twl603x_data.voffset[vdd_id - 1] = TWL6030_VOFFSET_0_UV; goto twl603x_smps_offset_get_end; } ret = i2cget(TWL6030_I2C_BUS, 0x48, 0xE0, &val); if (ret != 0) { fprintf(stderr, "%s(%u): could not read register! (%d)\n", __func__, vdd_id, ret); twl603x_data.voffset[vdd_id - 1] = TWL6030_VOFFSET_1_UV; goto twl603x_smps_offset_get_end; } dprintf("%s(%u): val=0x%02X\n", __func__, vdd_id, val); switch (vdd_id) { case OMAP4_VDD_MPU: if (cpu_is_omap4460()) { android_product_name_get(product_name); if (strstr(product_name, "Kindle") == NULL) fprintf(stderr, "%s(%u): invalid vdd_id! omap4460 uses TPS62361 for VDD_MPU\n", __func__, vdd_id); } val &= 0x08; break; case OMAP4_VDD_IVA: if (cpu_is_omap4470()) val &= 0x02; else val &= 0x10; break; case OMAP4_VDD_CORE: if (cpu_is_omap4460()) val &= 0x08; else if (cpu_is_omap4470()) val &= 0x10; else val &= 0x20; break; default: fprintf(stderr, "%s(%u): invalid vdd_id!\n", __func__, vdd_id); return TWL6030_VOFFSET_1_UV; } if (val != 0) twl603x_data.voffset[vdd_id - 1] = TWL6030_VOFFSET_1_UV; else twl603x_data.voffset[vdd_id - 1] = TWL6030_VOFFSET_0_UV; twl603x_smps_offset_get_end: dprintf("%s(%u): voffset=%lduV\n", __func__, vdd_id, twl603x_data.voffset[vdd_id - 1]); return twl603x_data.voffset[vdd_id - 1]; }