diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 0982190c..866fc75b 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -5,8 +5,8 @@ subdir-ccflags-y += -Werror obj-m += max9295.o obj-m += max9296.o -obj-m += max96712.o ifeq ($(findstring ack_src,$(NV_BUILD_KERNEL_OPTIONS)),) +obj-m += max96712.o obj-m += ar1335_common.o obj-m += lt6911uxc.o obj-m += nv_imx185.o @@ -19,4 +19,5 @@ obj-m += nv_ov5693.o obj-m += nv_ar0234.o obj-m += pca9570.o obj-m += nv_hawk_owl.o +obj-m += virtual_i2c_mux.o endif diff --git a/drivers/media/i2c/hawk_owl_mode_tbls.h b/drivers/media/i2c/hawk_owl_mode_tbls.h index 98548abb..16accdb9 100644 --- a/drivers/media/i2c/hawk_owl_mode_tbls.h +++ b/drivers/media/i2c/hawk_owl_mode_tbls.h @@ -73,89 +73,128 @@ static struct index_reg_8 i2c_address_trans_hawk_Quad_ser[] = { {0x00, AR0234_TABLE_END, 0x00} }; /* Deser/Ser I2C address translation */ -static struct index_reg_8 i2c_address_trans_Quad_hawk[] = { +enum { + OWL1, + OWL2, + OWL3, + OWL4, + HAWK1, + HAWK2, + HAWK3, + HAWK4 +}; + +static struct index_reg_8 i2c_address_trans_owl1[] = { + /* OWL A 0x18 -> 0x30 0x43 -> 0x31 */ + {0x94, 0x02be, 0x1d}, + {0x94, 0x0042, 0x60}, + {0x94, 0x0043, 0x30}, + {0x94, 0x0044, 0x62}, + {0x94, 0x0045, 0x86}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_owl2[] = { + /* OWL B 0x18 -> 0x32, 0x43 - > 0x33*/ + {0x96, 0x0042, 0x64}, + {0x96, 0x0043, 0x30}, + {0x96, 0x0044, 0x66}, + {0x96, 0x0045, 0x86}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_owl3[] = { + /* OWL C 0x18 -> 0x34, 0x43 -> 0x35 */ + {0x98, 0x0042, 0x68}, + {0x98, 0x0043, 0x30}, + {0x98, 0x0044, 0x6a}, + {0x98, 0x0045, 0x86}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_owl4[] = { + /* OWL D 0x18 -> 0x36, 0x43 -> 0x37 */ + {0x9a, 0x0042, 0x6c}, + {0x9a, 0x0043, 0x30}, + {0x9a, 0x0044, 0x6e}, + {0x9a, 0x0045, 0x86}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk1[] = { /* HAWK1 0x18 -> 0x30, 0x10 -> 0x31 */ {0x94, 0x0042, 0x60}, {0x94, 0x0043, 0x30}, {0x94, 0x0044, 0x62}, {0x94, 0x0045, 0x20}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk2[] = { /* HAWK2 0x18 -> 0x32, 0x10 -> 0x33 */ {0x96, 0x0042, 0x64}, {0x96, 0x0043, 0x30}, {0x96, 0x0044, 0x66}, {0x96, 0x0045, 0x20}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk3[] = { /* HAWK3 0x18 -> 0x34, 0x10 -> 0x35 */ {0x98, 0x0042, 0x68}, {0x98, 0x0043, 0x30}, {0x98, 0x0044, 0x6a}, {0x98, 0x0045, 0x20}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk4[] = { /* HAWK4 0x18 -> 0x36, 0x10 -> 0x37 */ {0x9a, 0x0042, 0x6c}, {0x9a, 0x0043, 0x30}, {0x9a, 0x0044, 0x6e}, {0x9a, 0x0045, 0x20}, - {0x00, AR0234_TABLE_END, 0x00} }; -static struct index_reg_8 i2c_address_trans_Triple_hawk[] = { - /* HAWK1 0x18 -> 0x30, 0x10 -> 0x31 */ - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x20}, - /* HAWK2 0x18 -> 0x32, 0x10 -> 0x33 */ - {0x96, 0x0042, 0x64}, - {0x96, 0x0043, 0x30}, - {0x96, 0x0044, 0x66}, - {0x96, 0x0045, 0x20}, - /* HAWK3 0x18 -> 0x34, 0x10 -> 0x35 */ - {0x98, 0x0042, 0x68}, - {0x98, 0x0043, 0x30}, - {0x98, 0x0044, 0x6a}, - {0x98, 0x0045, 0x20}, - {0x00, AR0234_TABLE_END, 0x00} +static struct index_reg_8 *hawk_owl_i2ctrans_table[] = { + [OWL1] = i2c_address_trans_owl1, + [OWL2] = i2c_address_trans_owl2, + [OWL3] = i2c_address_trans_owl3, + [OWL4] = i2c_address_trans_owl4, + [HAWK1] = i2c_address_trans_hawk1, + [HAWK2] = i2c_address_trans_hawk2, + [HAWK3] = i2c_address_trans_hawk3, + [HAWK4] = i2c_address_trans_hawk4, }; -static struct index_reg_8 i2c_address_trans_Dual_hawk[] = { - /* HAWK1 0x18 -> 0x30, 0x10 -> 0x31 */ - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x20}, - /* HAWK2 0x18 -> 0x32, 0x10 -> 0x33 */ - {0x96, 0x0042, 0x64}, - {0x96, 0x0043, 0x30}, - {0x96, 0x0044, 0x66}, - {0x96, 0x0045, 0x20}, - - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Single_hawk[] = { - /* HAWK1 0x18 -> 0x30, 0x10 -> 0x31 */ - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x20}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -/* HAWK EEPROM i2c adddress translation */ -static struct index_reg_8 i2c_address_trans_Quad_hawk_eeprom[] = { +/* HAWK/OWL EEPROM i2c adddress translation */ +static struct index_reg_8 i2c_address_trans_hawk1_eeprom[] = { {0x94, 0x0042, 0x80}, {0x94, 0x0043, 0xA8}, {0x94, 0x0044, 0x82}, {0x94, 0x0045, 0xAA}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk2_eeprom[] = { {0x96, 0x0042, 0x84}, {0x96, 0x0043, 0xA8}, {0x96, 0x0044, 0x86}, {0x96, 0x0045, 0xAA}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk3_eeprom[] = { {0x98, 0x0042, 0x88}, {0x98, 0x0043, 0xA8}, {0x98, 0x0044, 0x8A}, {0x98, 0x0045, 0xAA}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_hawk4_eeprom[] = { {0x9a, 0x0042, 0x8C}, {0x9a, 0x0043, 0xA8}, {0x9a, 0x0044, 0x8E}, @@ -163,42 +202,50 @@ static struct index_reg_8 i2c_address_trans_Quad_hawk_eeprom[] = { {0x00, AR0234_TABLE_END, 0x00} }; -static struct index_reg_8 i2c_address_trans_Triple_hawk_eeprom[] = { - {0x94, 0x0042, 0x80}, +static struct index_reg_8 i2c_address_trans_owl1_eeprom[] = { + {0x94, 0x0042, 0x70}, {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x82}, + {0x94, 0x0044, 0x72}, {0x94, 0x0045, 0xAA}, - {0x96, 0x0042, 0x84}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_owl2_eeprom[] = { + {0x96, 0x0042, 0x74}, {0x96, 0x0043, 0xA8}, - {0x96, 0x0044, 0x86}, + {0x96, 0x0044, 0x76}, {0x96, 0x0045, 0xAA}, - {0x98, 0x0042, 0x88}, + {0x00, AR0234_TABLE_END, 0x00} +}; + +static struct index_reg_8 i2c_address_trans_owl3_eeprom[] = { + {0x98, 0x0042, 0x78}, {0x98, 0x0043, 0xA8}, - {0x98, 0x0044, 0x8A}, + {0x98, 0x0044, 0x7A}, {0x98, 0x0045, 0xAA}, {0x00, AR0234_TABLE_END, 0x00} }; -static struct index_reg_8 i2c_address_trans_Dual_hawk_eeprom[] = { - {0x94, 0x0042, 0x80}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x82}, - {0x94, 0x0045, 0xAA}, - {0x96, 0x0042, 0x84}, - {0x96, 0x0043, 0xA8}, - {0x96, 0x0044, 0x86}, - {0x96, 0x0045, 0xAA}, +static struct index_reg_8 i2c_address_trans_owl4_eeprom[] = { + {0x9a, 0x0042, 0x7C}, + {0x9a, 0x0043, 0xA8}, + {0x9a, 0x0044, 0x7E}, + {0x9a, 0x0045, 0xAA}, {0x00, AR0234_TABLE_END, 0x00} }; -static struct index_reg_8 i2c_address_trans_Single_hawk_eeprom[] = { - {0x94, 0x0042, 0x80}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x82}, - {0x94, 0x0045, 0xAA}, - {0x00, AR0234_TABLE_END, 0x00} +static struct index_reg_8 *hawk_owl_eeprom_i2ctrans_table[] = { + [OWL1] = i2c_address_trans_owl1_eeprom, + [OWL2] = i2c_address_trans_owl2_eeprom, + [OWL3] = i2c_address_trans_owl3_eeprom, + [OWL4] = i2c_address_trans_owl4_eeprom, + [HAWK1] = i2c_address_trans_hawk1_eeprom, + [HAWK2] = i2c_address_trans_hawk2_eeprom, + [HAWK3] = i2c_address_trans_hawk3_eeprom, + [HAWK4] = i2c_address_trans_hawk4_eeprom, }; +/* Owl */ static struct index_reg_8 i2c_address_trans_owl_Single_ser[] = { {0x52, 0x0006, 0x11}, {0x80, 0x0000, 0x94}, @@ -235,139 +282,6 @@ static struct index_reg_8 i2c_address_trans_owl_Quad_ser[] = { {0x00, AR0234_TABLE_END, 0x00} }; -static struct index_reg_8 i2c_address_trans_Quad_owl[] = { - /* OWL A 0x18 -> 0x30 0x43 -> 0x31 */ - {0x94, 0x02be, 0x1d}, - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x86}, - - /* OWL B 0x18 -> 0x32, 0x43 - > 0x33*/ - {0x96, 0x0042, 0x64}, - {0x96, 0x0043, 0x30}, - {0x96, 0x0044, 0x66}, - {0x96, 0x0045, 0x86}, - - /* OWL C 0x18 -> 0x34, 0x43 -> 0x35 */ - {0x98, 0x0042, 0x68}, - {0x98, 0x0043, 0x30}, - {0x98, 0x0044, 0x6a}, - {0x98, 0x0045, 0x86}, - - /* OWL D 0x18 -> 0x36, 0x43 -> 0x37 */ - {0x9a, 0x0042, 0x6c}, - {0x9a, 0x0043, 0x30}, - {0x9a, 0x0044, 0x6e}, - {0x9a, 0x0045, 0x86}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Triple_owl[] = { - /* OWL A 0x18 -> 0x30 0x43 -> 0x31 */ - {0x94, 0x02be, 0x1d}, - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x86}, - - /* OWL B 0x18 -> 0x32, 0x43 - > 0x33*/ - {0x96, 0x0042, 0x64}, - {0x96, 0x0043, 0x30}, - {0x96, 0x0044, 0x66}, - {0x96, 0x0045, 0x86}, - - /* OWL C 0x18 -> 0x34, 0x43 -> 0x35 */ - {0x98, 0x0042, 0x68}, - {0x98, 0x0043, 0x30}, - {0x98, 0x0044, 0x6a}, - {0x98, 0x0045, 0x86}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Dual_owl[] = { - /* OWL A 0x18 -> 0x30 0x43 -> 0x31 */ - {0x94, 0x02be, 0x1d}, - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x86}, - - /* OWL B 0x18 -> 0x32, 0x43 - > 0x33*/ - {0x96, 0x0042, 0x64}, - {0x96, 0x0043, 0x30}, - {0x96, 0x0044, 0x66}, - {0x96, 0x0045, 0x86}, - - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Single_owl[] = { - /* OWL A 0x18 -> 0x30 0x43 -> 0x31 */ - {0x94, 0x02be, 0x1d}, - {0x94, 0x0042, 0x60}, - {0x94, 0x0043, 0x30}, - {0x94, 0x0044, 0x62}, - {0x94, 0x0045, 0x86}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Single_owl_eeprom[] = { - {0x94, 0x0042, 0x70}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x72}, - {0x94, 0x0045, 0xAA}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Dual_owl_eeprom[] = { - {0x94, 0x0042, 0x70}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x72}, - {0x94, 0x0045, 0xAA}, - {0x96, 0x0042, 0x74}, - {0x96, 0x0043, 0xA8}, - {0x96, 0x0044, 0x76}, - {0x96, 0x0045, 0xAA}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Triple_owl_eeprom[] = { - {0x94, 0x0042, 0x70}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x72}, - {0x94, 0x0045, 0xAA}, - {0x96, 0x0042, 0x74}, - {0x96, 0x0043, 0xA8}, - {0x96, 0x0044, 0x76}, - {0x96, 0x0045, 0xAA}, - {0x98, 0x0042, 0x78}, - {0x98, 0x0043, 0xA8}, - {0x98, 0x0044, 0x7A}, - {0x98, 0x0045, 0xAA}, - {0x00, AR0234_TABLE_END, 0x00} -}; - -static struct index_reg_8 i2c_address_trans_Quad_owl_eeprom[] = { - {0x94, 0x0042, 0x70}, - {0x94, 0x0043, 0xA8}, - {0x94, 0x0044, 0x72}, - {0x94, 0x0045, 0xAA}, - {0x96, 0x0042, 0x74}, - {0x96, 0x0043, 0xA8}, - {0x96, 0x0044, 0x76}, - {0x96, 0x0045, 0xAA}, - {0x98, 0x0042, 0x78}, - {0x98, 0x0043, 0xA8}, - {0x98, 0x0044, 0x7A}, - {0x98, 0x0045, 0xAA}, - {0x9a, 0x0042, 0x7C}, - {0x9a, 0x0043, 0xA8}, - {0x9a, 0x0044, 0x7E}, - {0x9a, 0x0045, 0xAA}, - {0x00, AR0234_TABLE_END, 0x00} -}; - static struct index_reg_8 ar0234_Hawk_SingleLink_Dser_Ser[] = { {0x52, 0x1458, 0x28}, {0x52, 0x1459, 0x68}, @@ -434,15 +348,27 @@ static struct index_reg_8 ar0234_Hawk_SingleLink_Dser_Ser[] = { {0x52, 0x0952, 0x41}, // Output FE, VC1 {0x52, 0x08A2, 0xF0}, - {0x94, 0x02be, 0x90}, // Enable sensor power down pin. - {0x94, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x94, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x94, 0x02cb, 0x60}, // Enable sensor reset pin. {0x94, 0x02d3, 0x90}, // Enable sensor power down pin. {0x94, 0x02d4, 0x60}, // Enable sensor reset pin. {0x94, 0x02d6, 0x90}, // Enable sensor power down pin. {0x94, 0x02d7, 0x60}, // Enable sensor reset pin. + /* Enable IMU's */ + /* For Hawk1 */ + {0x94, 0x02be, 0x83}, // max9295D MFP0-- ACCEL interrupt + {0x94, 0x02bf, 0x31}, //ID = 0b'10001 + {0x94, 0x02c0, 0x51}, //ID = 0b'10001 + {0x52, 0x0310, 0x84}, // max96712 MFF5---ACCEL1 interrupt + {0x52, 0x0311, 0xb1}, // ID = 0b'10001 + {0x52, 0x0312, 0x51}, // ID = 0b'10001 + + {0x94, 0x02c4, 0x83}, // max9295D MFP2-- gyro interrup + {0x94, 0x02c5, 0x33}, //ID = 0b'10003 + {0x94, 0x02c6, 0x53}, //ID = 0b'10003 + {0x52, 0x0316, 0x84}, // max96712 MTF7---gyro1 interrupt + {0x52, 0x0317, 0xb3}, // ID = 0b'10003 + {0x52, 0x0318, 0x53}, // ID = 0b'10003 + {0x00,AR0234_TABLE_END,0x00} }; @@ -540,22 +466,37 @@ static struct index_reg_8 ar0234_Hawk_DualLink_Dser_Ser[] = { {0x52, 0x09D2, 0x41}, // Output FE, VC1 {0x52, 0x08A2, 0xF0}, - {0x94, 0x02be, 0x90}, // Enable sensor power down pin. - {0x94, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x94, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x94, 0x02cb, 0x60}, // Enable sensor reset pin. {0x94, 0x02d3, 0x90}, // Enable sensor power down pin. {0x94, 0x02d4, 0x60}, // Enable sensor reset pin. {0x94, 0x02d6, 0x90}, // Enable sensor power down pin. {0x94, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x96, 0x02be, 0x90}, // Enable sensor power down pin. - {0x96, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x96, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x96, 0x02cb, 0x60}, // Enable sensor reset pin. {0x96, 0x02d3, 0x90}, // Enable sensor power down pin. {0x96, 0x02d4, 0x60}, // Enable sensor reset pin. {0x96, 0x02d6, 0x90}, // Enable sensor power down pin. {0x96, 0x02d7, 0x60}, // Enable sensor reset pin. + + /* Enable IMU's */ + /* For Hawk1 */ + {0x94, 0x02be, 0x83}, // max9295D MFP0-- ACCEL interrupt + {0x94, 0x02bf, 0x31}, //ID = 0b'10001 + {0x94, 0x02c0, 0x51}, //ID = 0b'10001 + {0x52, 0x0310, 0x84}, // max96712 MFF5---ACCEL1 interrupt + {0x52, 0x0311, 0xb1}, // ID = 0b'10001 + {0x52, 0x0312, 0x51}, // ID = 0b'10001 + + {0x94, 0x02c4, 0x83}, // max9295D MFP2- gyro interrup + {0x94, 0x02c5, 0x33}, //ID = 0b'10003 + {0x94, 0x02c6, 0x53}, //ID = 0b'10003 + {0x52, 0x0316, 0x84}, // max96712 MTF7---gyro1 interrupt + {0x52, 0x0317, 0xb3}, // ID = 0b'10003 + {0x52, 0x0318, 0x53}, // ID = 0b'10003 + + /* For Hawk2 */ + {0x96, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x96, 0x02bf, 0x00}, + {0x96, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x94, 0x02c8, 0x00}, + {0x00,AR0234_TABLE_END,0x00} }; @@ -675,31 +616,46 @@ static struct index_reg_8 ar0234_Hawk_TripleLink_Dser_Ser[] = { {0x52, 0x0A52, 0x41}, // Output FE on VC1 {0x52, 0x08A2, 0xF0}, - {0x94, 0x02be, 0x90}, // Enable sensor power down pin. - {0x94, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x94, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x94, 0x02cb, 0x60}, // Enable sensor reset pin. {0x94, 0x02d3, 0x90}, // Enable sensor power down pin. {0x94, 0x02d4, 0x60}, // Enable sensor reset pin. {0x94, 0x02d6, 0x90}, // Enable sensor power down pin. {0x94, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x96, 0x02be, 0x90}, // Enable sensor power down pin. - {0x96, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x96, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x96, 0x02cb, 0x60}, // Enable sensor reset pin. {0x96, 0x02d3, 0x90}, // Enable sensor power down pin. {0x96, 0x02d4, 0x60}, // Enable sensor reset pin. {0x96, 0x02d6, 0x90}, // Enable sensor power down pin. {0x96, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x98, 0x02be, 0x90}, // Enable sensor power down pin. - {0x98, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x98, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x98, 0x02cb, 0x60}, // Enable sensor reset pin. {0x98, 0x02d3, 0x90}, // Enable sensor power down pin. {0x98, 0x02d4, 0x60}, // Enable sensor reset pin. {0x98, 0x02d6, 0x90}, // Enable sensor power down pin. {0x98, 0x02d7, 0x60}, // Enable sensor reset pin. + /* Enable IMU's */ + /* For Hawk1 */ + {0x94, 0x02be, 0x83}, // max9295D MFP0-- ACCEL interrupt + {0x94, 0x02bf, 0x31}, //ID = 0b'10001 + {0x94, 0x02c0, 0x51}, //ID = 0b'10001 + {0x52, 0x0310, 0x84}, // max96712 MFF5---ACCEL1 interrupt + {0x52, 0x0311, 0xb1}, // ID = 0b'10001 + {0x52, 0x0312, 0x51}, // ID = 0b'10001 + + {0x94, 0x02c4, 0x83}, // max9295D MFP3-- gyro interrup + {0x94, 0x02c5, 0x33}, //ID = 0b'10003 + {0x94, 0x02c6, 0x53}, //ID = 0b'10003 + {0x52, 0x0316, 0x84}, // max96712 MTF7---gyro1 interrupt + {0x52, 0x0317, 0xb3}, // ID = 0b'10003 + {0x52, 0x0318, 0x53}, // ID = 0b'10003 + + /* For Hawk2 */ + {0x96, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x96, 0x02bf, 0x00}, + {0x96, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x94, 0x02c8, 0x00}, + /* For Hawk3 */ + {0x98, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x98, 0x02bf, 0x00}, + {0x98, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x98, 0x02c8, 0x00}, + {0x00,AR0234_TABLE_END,0x00} }; @@ -846,42 +802,58 @@ static struct index_reg_8 ar0234_Hawk_QuadLink_Dser_Ser[] = { {0x52, 0x0AD2, 0x41}, // Output FE on VC1 {0x52, 0x08A2, 0xF0}, - {0x94, 0x02be, 0x90}, // Enable sensor power down pin. - {0x94, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x94, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x94, 0x02cb, 0x60}, // Enable sensor reset pin. {0x94, 0x02d3, 0x90}, // Enable sensor power down pin. {0x94, 0x02d4, 0x60}, // Enable sensor reset pin. {0x94, 0x02d6, 0x90}, // Enable sensor power down pin. {0x94, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x96, 0x02be, 0x90}, // Enable sensor power down pin. - {0x96, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x96, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x96, 0x02cb, 0x60}, // Enable sensor reset pin. {0x96, 0x02d3, 0x90}, // Enable sensor power down pin. {0x96, 0x02d4, 0x60}, // Enable sensor reset pin. {0x96, 0x02d6, 0x90}, // Enable sensor power down pin. {0x96, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x98, 0x02be, 0x90}, // Enable sensor power down pin. - {0x98, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x98, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x98, 0x02cb, 0x60}, // Enable sensor reset pin. {0x98, 0x02d3, 0x90}, // Enable sensor power down pin. {0x98, 0x02d4, 0x60}, // Enable sensor reset pin. {0x98, 0x02d6, 0x90}, // Enable sensor power down pin. {0x98, 0x02d7, 0x60}, // Enable sensor reset pin. - {0x9a, 0x02be, 0x90}, // Enable sensor power down pin. - {0x9a, 0x02bf, 0x60}, // Enable sensor reset pin. - {0x9a, 0x02ca, 0x80}, // Enable sensor power down pin. - {0x9a, 0x02cb, 0x60}, // Enable sensor reset pin. {0x9a, 0x02d3, 0x90}, // Enable sensor power down pin. {0x9a, 0x02d4, 0x60}, // Enable sensor reset pin. {0x9a, 0x02d6, 0x90}, // Enable sensor power down pin. {0x9a, 0x02d7, 0x60}, // Enable sensor reset pin. + /* Enable IMU's */ + /* For Hawk1 */ + {0x94, 0x02be, 0x83}, // max9295D MFP0-- ACCEL interrupt + {0x94, 0x02bf, 0x31}, //ID = 0b'10001 + {0x94, 0x02c0, 0x51}, //ID = 0b'10001 + {0x52, 0x0310, 0x84}, // max96712 MFF5---ACCEL1 interrupt + {0x52, 0x0311, 0xb1}, // ID = 0b'10001 + {0x52, 0x0312, 0x51}, // ID = 0b'10001 + + {0x94, 0x02c4, 0x83}, // max9295D MFP2-- gyro interrup + {0x94, 0x02c5, 0x33}, //ID = 0b'10003 + {0x94, 0x02c6, 0x53}, //ID = 0b'10003 + {0x52, 0x0316, 0x84}, // max96712 MTF7---gyro1 interrupt + {0x52, 0x0317, 0xb3}, // ID = 0b'10003 + {0x52, 0x0318, 0x53}, // ID = 0b'10003 + + /* For Hawk2 */ + {0x96, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x96, 0x02bf, 0x00}, + {0x96, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x94, 0x02c8, 0x00}, + /* For Hawk3 */ + {0x98, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x98, 0x02bf, 0x00}, + {0x98, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x98, 0x02c8, 0x00}, + /* For Hawk4 */ + {0x9a, 0x02be, 0x03}, // Disable output, max9295D MFP0-- ACCEL interrupt + {0x9a, 0x02bf, 0x00}, + {0x9a, 0x02c7, 0x03}, // Disable output, max9295D MFP3-- gyro interrup + {0x9a, 0x02c8, 0x00}, {0x00,AR0234_TABLE_END,0x00} }; + /* Internal Fsync for Hawk */ static struct index_reg_8 Hawk_SingleLink_Dser_InFsync[] = { /* Enable internal Fsync */ diff --git a/drivers/media/i2c/max96712.c b/drivers/media/i2c/max96712.c index 469f028f..8ddbb499 100644 --- a/drivers/media/i2c/max96712.c +++ b/drivers/media/i2c/max96712.c @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include struct max96712 { @@ -148,6 +151,24 @@ static const struct file_operations max96712_debugfs_fops = { .release = single_release, }; +static int max96712_power_on(struct max96712 *priv) +{ + struct i2c_client *i2c_client = priv->i2c_client; + struct device_node *np = i2c_client->dev.of_node; + unsigned int pwdn_gpio = 0; + + if(np) { + pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); + dev_info(&i2c_client->dev,"%s: pwdn_gpio = %d\n",__func__,pwdn_gpio); + } + if (pwdn_gpio > 0) { + gpio_direction_output(pwdn_gpio, 1); + gpio_set_value(pwdn_gpio, 1); + msleep(100); + } + return 0; +} + static int max96712_debugfs_init(const char *dir_name, struct dentry **d_entry, struct dentry **f_entry, @@ -228,6 +249,13 @@ static int max96712_probe(struct i2c_client *client, } mutex_init(&max96712_rw); + + err = max96712_power_on(priv); + if (err) { + dev_err(&client->dev, "Failed to power on err =%d\n",err); + return err; + } + err = max96712_debugfs_init(NULL, NULL, NULL, priv); if (err) return err; diff --git a/drivers/media/i2c/nv_hawk_owl.c b/drivers/media/i2c/nv_hawk_owl.c index 59d652a2..53bac583 100644 --- a/drivers/media/i2c/nv_hawk_owl.c +++ b/drivers/media/i2c/nv_hawk_owl.c @@ -236,6 +236,7 @@ struct ar0234 { struct tegracam_device *tc_dev; u32 channel; u32 sync_sensor_index; + const char *sensor_name; NvCamSyncSensorCalibData EepromCalib; }; static const struct regmap_config sensor_regmap_config = { @@ -269,7 +270,7 @@ static inline int ar0234_read_reg(struct camera_common_data *s_data, static int ar0234_write_reg(struct camera_common_data *s_data, u16 addr, u16 val) { - int err; + int err = 0; struct device *dev = s_data->dev; err = regmap_write(s_data->regmap, addr, val); if (err) @@ -287,6 +288,7 @@ static int ar0234_write_table(struct ar0234 *priv, int retry = 5; int retry_seraddr = 0x84; dev_dbg(dev, "%s: channel %d, ", __func__, priv->channel); + while (table[i].source != 0x00) { if (table[i].source == 0x06) { retry = 1; @@ -325,12 +327,12 @@ retry_serdes: 0/*channel-num*/, table[i].addr, (u8)table[i].val); else ret = max96712_write_reg_Dser(table[i].source, - priv->channel, table[i].addr, (u8)table[i].val); + priv->channel, table[i].addr, (u8)table[i].val); /* To handle ser address change from 0x80 to 0x84 * after link enable at deser*/ if (ret && (0x80 == table[i].source)) { ret = max96712_write_reg_Dser(retry_seraddr, - priv->channel, table[i].addr, (u8)table[i].val); + priv->channel, table[i].addr, (u8)table[i].val); } if (ret && (table[i].addr != 0x0000)) { @@ -386,105 +388,71 @@ static int ar0234_hawk_link_check(struct ar0234 *priv) } } +static int sensor_name_to_enum(struct ar0234 *priv) +{ + if (!strcmp(priv->sensor_name, "OWL1")) + return OWL1; + else if (!strcmp(priv->sensor_name, "OWL2")) + return OWL2; + else if (!strcmp(priv->sensor_name, "OWL3")) + return OWL3; + else if (!strcmp(priv->sensor_name, "OWL4")) + return OWL4; + else if (!strcmp(priv->sensor_name, "HAWK1")) + return HAWK1; + else if (!strcmp(priv->sensor_name, "HAWK2")) + return HAWK2; + else if (!strcmp(priv->sensor_name, "HAWK3")) + return HAWK3; + else if (!strcmp(priv->sensor_name, "HAWK4")) + return HAWK4; + else + pr_err("%s: Sensor name %s is not matching!!\n",__func__,priv->sensor_name); + return -1; +} + static int ar0234_hawk_owl_i2ctrans(struct ar0234 *priv) { int err = 0; if(ar0234_hawk_link_check(priv) == 4) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Quad_owl); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } else if ((!priv->channel) || (2 == priv->sync_sensor_index)) { - err = ar0234_write_table(priv, i2c_address_trans_Quad_hawk); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } + err = ar0234_write_table(priv, hawk_owl_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 3) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Triple_owl); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } else if ((!priv->channel) || (2 == priv->sync_sensor_index)) { - err = ar0234_write_table(priv, i2c_address_trans_Triple_hawk); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } + err = ar0234_write_table(priv, hawk_owl_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 2) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Dual_owl); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } else if ((!priv->channel) || (2 == priv->sync_sensor_index)) { - err = ar0234_write_table(priv, i2c_address_trans_Dual_hawk); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } + err = ar0234_write_table(priv, hawk_owl_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 1) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Single_owl); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } else if ((!priv->channel) || (2 == priv->sync_sensor_index)) { - err = ar0234_write_table(priv, i2c_address_trans_Single_hawk); - if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); - } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); - } - } + err = ar0234_write_table(priv, hawk_owl_i2ctrans_table[sensor_name_to_enum(priv)]); } return err; } -static int ar0234_enable_pwdn_gpio(struct camera_common_data *s_data) + +static int hawk_owl_ser_i2c_trans(struct camera_common_data *s_data) { int err = 0; - struct camera_common_power_rail *pw = s_data->power; struct ar0234 *priv = (struct ar0234 *) s_data->priv; + struct device *dev = s_data->dev; static int haw_flag = 0, owl_flag = 0; - if (pw->pwdn_gpio > 0) - gpio_set_value(pw->pwdn_gpio, 1); - msleep(100); + /* Serializer i2c address trans */ if(ar0234_hawk_link_check(priv) == 4) { if ((1 == priv->channel) && !owl_flag) { err = ar0234_write_table(priv, i2c_address_trans_owl_Quad_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } owl_flag++; } else if ((!priv->channel) && !haw_flag) { err = ar0234_write_table(priv, i2c_address_trans_hawk_Quad_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } haw_flag++; } @@ -492,18 +460,18 @@ static int ar0234_enable_pwdn_gpio(struct camera_common_data *s_data) if ((1 == priv->channel) && !owl_flag) { err = ar0234_write_table(priv, i2c_address_trans_owl_Triple_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } owl_flag++; } else if ((!priv->channel) && !haw_flag) { err = ar0234_write_table(priv, i2c_address_trans_hawk_Triple_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } haw_flag++; } @@ -511,18 +479,18 @@ static int ar0234_enable_pwdn_gpio(struct camera_common_data *s_data) if ((1 == priv->channel) && !owl_flag) { err = ar0234_write_table(priv, i2c_address_trans_owl_Dual_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } owl_flag++; } else if ((!priv->channel) && !haw_flag) { err = ar0234_write_table(priv, i2c_address_trans_hawk_Dual_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } haw_flag++; } @@ -530,18 +498,18 @@ static int ar0234_enable_pwdn_gpio(struct camera_common_data *s_data) if ((1 == priv->channel) && !owl_flag) { err = ar0234_write_table(priv, i2c_address_trans_owl_Single_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } owl_flag++; } else if ((!priv->channel) && !haw_flag) { err = ar0234_write_table(priv, i2c_address_trans_hawk_Single_ser); if (err) { - pr_err("%s: Failed to do i2c address trans..\n",__func__); + dev_err(dev,"%s: Failed to do i2c address trans..\n",__func__); } else { - pr_err("%s: Successfully done I2c address trans..\n",__func__); + dev_info(dev,"%s: Successfully done I2c address trans..\n",__func__); } haw_flag++; } @@ -757,43 +725,53 @@ static int ar0234_fill_eeprom(struct tegracam_device *tc_dev, struct v4l2_ctrl *ctrl) { struct ar0234 *priv = tc_dev->priv; - LiEeprom_Content_Struct tmp; + LiEeprom_Content_Struct *tmp; u32 test = 0; + switch (ctrl->id) { case TEGRA_CAMERA_CID_STEREO_EEPROM: + tmp = kmalloc(sizeof(LiEeprom_Content_Struct), + GFP_KERNEL); + if (tmp == NULL) + return -ENOMEM; + memset(&(priv->EepromCalib), 0, sizeof(NvCamSyncSensorCalibData)); memset(ctrl->p_new.p, 0, sizeof(NvCamSyncSensorCalibData)); - memcpy(&tmp, priv->eeprom_buf, sizeof(LiEeprom_Content_Struct)); + memcpy(tmp, priv->eeprom_buf, sizeof(LiEeprom_Content_Struct)); if (priv->sync_sensor_index == 1) { - priv->EepromCalib.cam_intr = tmp.left_cam_intr; + priv->EepromCalib.cam_intr = tmp->left_cam_intr; } else if (priv->sync_sensor_index == 2) { - priv->EepromCalib.cam_intr = tmp.right_cam_intr; + priv->EepromCalib.cam_intr = tmp->right_cam_intr; } else { - priv->EepromCalib.cam_intr = tmp.left_cam_intr; + priv->EepromCalib.cam_intr = tmp->left_cam_intr; } - priv->EepromCalib.cam_extr = tmp.cam_extr; - priv->EepromCalib.imu_present = tmp.imu_present; - priv->EepromCalib.imu = tmp.imu; - memcpy(priv->EepromCalib.serial_number, tmp.serial_number, - CAMERA_MAX_SN_LENGTH); + priv->EepromCalib.cam_extr = tmp->cam_extr; + priv->EepromCalib.imu_present = tmp->imu_present; + priv->EepromCalib.imu = tmp->imu; + memcpy(priv->EepromCalib.serial_number, tmp->serial_number, + CAMERA_MAX_SN_LENGTH); if (priv->sync_sensor_index == 1) - priv->EepromCalib.rls = tmp.left_rls; + priv->EepromCalib.rls = tmp->left_rls; else if (priv->sync_sensor_index == 2) - priv->EepromCalib.rls = tmp.right_rls; + priv->EepromCalib.rls = tmp->right_rls; else - priv->EepromCalib.rls = tmp.left_rls; + priv->EepromCalib.rls = tmp->left_rls; memcpy(ctrl->p_new.p, (u8 *)&(priv->EepromCalib), sizeof(NvCamSyncSensorCalibData)); + + kfree(tmp); break; default: return -EINVAL; } + memcpy(&test, &(priv->EepromCalib.cam_intr.fx), 4); ctrl->p_cur.p = ctrl->p_new.p; return 0; } + static struct tegracam_ctrl_ops ar0234_ctrl_ops = { .numctrls = ARRAY_SIZE(ctrl_cid_list), .ctrl_cid_list = ctrl_cid_list, @@ -852,7 +830,8 @@ static int ar0234_set_mode(struct tegracam_device *tc_dev) struct camera_common_data *s_data = tc_dev->s_data; struct device *dev = tc_dev->dev; const struct of_device_id *match; - int err; + int err = 0; + match = of_match_device(ar0234_of_match, dev); if (!match) { dev_err(dev, "Failed to find matching dt id\n"); @@ -865,6 +844,7 @@ static int ar0234_set_mode(struct tegracam_device *tc_dev) return -EINVAL; dev_err(dev, "%s: mode index:%d\n", __func__,s_data->mode_prop_idx); /* Moved the sensor mode table write during probe time, to reduce Stream on time */ + return 0; } static int ar0234_start_streaming(struct tegracam_device *tc_dev) @@ -877,6 +857,7 @@ static int ar0234_start_streaming(struct tegracam_device *tc_dev) if (err) return err; } + err = ar0234_write_table(priv, mode_table[AR0234_MODE_START_STREAM]); if (err) @@ -1028,80 +1009,16 @@ static int ar0234_hawk_owl_EEPROM_address_trans(struct ar0234 *priv) { int err = 0; - /* i2c address trans for EEPROM access */ if(ar0234_hawk_link_check(priv) == 4) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Quad_owl_eeprom); - if (err) { - pr_err("Owl camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Owl camera Eeprom i2c address trans success!!!\n"); - } - } else if ((!priv->channel) || (priv->sync_sensor_index == 2)) { - err = ar0234_write_table(priv, i2c_address_trans_Quad_hawk_eeprom); - if (err) { - pr_err("Hawk camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Hawk camera Eeprom i2c address trans success!!!\n"); - } - } + err = ar0234_write_table(priv, hawk_owl_eeprom_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 3) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Triple_owl_eeprom); - if (err) { - pr_err("Owl camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Owl camera Eeprom i2c address trans success!!!\n"); - } - } else if ((!priv->channel) || (priv->sync_sensor_index == 2)) { - err = ar0234_write_table(priv, i2c_address_trans_Triple_hawk_eeprom); - if (err) { - pr_err("Hawk camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Hawk camera Eeprom i2c address trans success!!!\n"); - } - } + err = ar0234_write_table(priv, hawk_owl_eeprom_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 2) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Dual_owl_eeprom); - if (err) { - pr_err("Owl camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Owl camera Eeprom i2c address trans success!!!\n"); - } - } else if ((!priv->channel) || (priv->sync_sensor_index == 2)) { - err = ar0234_write_table(priv, i2c_address_trans_Dual_hawk_eeprom); - if (err) { - pr_err("Hawk camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Hawk camera Eeprom i2c address trans success!!!\n"); - } - } + err = ar0234_write_table(priv, hawk_owl_eeprom_i2ctrans_table[sensor_name_to_enum(priv)]); } else if(ar0234_hawk_link_check(priv) == 1) { - if ((1 == priv->channel)) { - err = ar0234_write_table(priv, i2c_address_trans_Single_owl_eeprom); - if (err) { - pr_err("Owl camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Owl camera Eeprom i2c address trans success!!!\n"); - } - } else if ((!priv->channel) || (priv->sync_sensor_index == 2)) { - err = ar0234_write_table(priv, i2c_address_trans_Single_hawk_eeprom); - if (err) { - pr_err("Hawk camera Eeprom i2c address trans error\n"); - return err; - } else { - pr_err("Hawk camera Eeprom i2c address trans success!!!\n"); - } - } + err = ar0234_write_table(priv, hawk_owl_eeprom_i2ctrans_table[sensor_name_to_enum(priv)]); } + return err; } @@ -1332,23 +1249,25 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv) { int err = 0; static int hawk_flag = 0, owl_flag = 0; + struct camera_common_data *s_data = priv->s_data; + struct device *dev = s_data->dev; if(ar0234_hawk_link_check(priv) == 4) { if ((1 == priv->channel) && (!owl_flag)) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_OWL_QUADLINK_DSER_SER]); if (err) - pr_err("%s: Failed to do OWL mode table..\n",__func__); + dev_err(dev,"%s: Failed to do OWL mode table..\n",__func__); else - pr_err("%s: Successfully done OWL mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done OWL mode table ..\n",__func__); owl_flag++; owl_links = QUAD_LINK; } if ((!priv->channel) && !hawk_flag) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_HAWK_QUADLINK_DSER_SER]); if (err) - pr_err("%s: Failed to do Hawk mode table..\n",__func__); + dev_err(dev,"%s: Failed to do Hawk mode table..\n",__func__); else - pr_err("%s: Successfully done Hawk mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done Hawk mode table ..\n",__func__); hawk_flag++; hawk_links = QUAD_LINK; } @@ -1356,18 +1275,18 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv) if ((1 == priv->channel) && (!owl_flag)) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_OWL_TRIPLELINK_DSER_SER]); if (err) - pr_err("%s: Failed to do OWL mode table..\n",__func__); + dev_err(dev,"%s: Failed to do OWL mode table..\n",__func__); else - pr_err("%s: Successfully done OWL mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done OWL mode table ..\n",__func__); owl_flag++; owl_links = TRIPLE_LINK; } if ((!priv->channel) && !hawk_flag) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_HAWK_TRIPLELINK_DSER_SER]); if (err) - pr_err("%s: Failed to do Hawk mode table..\n",__func__); + dev_err(dev,"%s: Failed to do Hawk mode table..\n",__func__); else - pr_err("%s: Successfully done Hawk mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done Hawk mode table ..\n",__func__); hawk_flag++; hawk_links = TRIPLE_LINK; } @@ -1375,18 +1294,18 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv) if ((1 == priv->channel) && (!owl_flag)) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_OWL_DUALLINK_DSER_SER]); if (err) - pr_err("%s: Failed to do OWL mode table..\n",__func__); + dev_err(dev,"%s: Failed to do OWL mode table..\n",__func__); else - pr_err("%s: Successfully done OWL mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done OWL mode table ..\n",__func__); owl_flag++; owl_links = DUAL_LINK; } if ((!priv->channel) && !hawk_flag) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_HAWK_DUALLINK_DSER_SER]); if (err) - pr_err("%s: Failed to do Hawk mode table..\n",__func__); + dev_err(dev,"%s: Failed to do Hawk mode table..\n",__func__); else - pr_err("%s: Successfully done Hawk mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done Hawk mode table ..\n",__func__); hawk_flag++; hawk_links = DUAL_LINK; } @@ -1394,18 +1313,18 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv) if ((1 == priv->channel) && (!owl_flag)) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_OWL_SINGLELINK_DSER_SER]); if (err) - pr_err("%s: Failed to do OWL mode table..\n",__func__); + dev_err(dev,"%s: Failed to do OWL mode table..\n",__func__); else - pr_err("%s: Successfully done OWL mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done OWL mode table ..\n",__func__); owl_flag++; owl_links = SINGLE_LINK; } if ((!priv->channel) && !hawk_flag) { err = ar0234_write_table(priv, mode_table[AR0234_MODE_HAWK_SINGLELINK_DSER_SER]); if (err) - pr_err("%s: Failed to do Hawk mode table..\n",__func__); + dev_err(dev,"%s: Failed to do Hawk mode table..\n",__func__); else - pr_err("%s: Successfully done Hawk mode table ..\n",__func__); + dev_info(dev,"%s: Successfully done Hawk mode table ..\n",__func__); hawk_flag++; hawk_links = SINGLE_LINK; } @@ -1413,8 +1332,12 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv) return err; } +#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE +static int ar0234_probe(struct i2c_client *client) +#else static int ar0234_probe(struct i2c_client *client, const struct i2c_device_id *id) +#endif { struct device *dev = &client->dev; struct device_node *node = dev->of_node; @@ -1442,9 +1365,13 @@ static int ar0234_probe(struct i2c_client *client, if (err) dev_err(dev, "channel not found\n"); priv->channel = str[0] - 'a'; - dev_err(dev, "%s: channel %d\n", __func__, priv->channel); + dev_info(dev, "%s: channel %d\n", __func__, priv->channel); + err = of_property_read_string(node, "sync_sensor", &priv->sensor_name); + if (err) + dev_err(dev, "sync_sensor not found\n"); + dev_info(dev,"%s: sync_sensor = %s \n", __func__, priv->sensor_name); err = of_property_read_u32(node, "sync_sensor_index", &priv->sync_sensor_index); if (err) @@ -1468,8 +1395,8 @@ static int ar0234_probe(struct i2c_client *client, priv->subdev = &tc_dev->s_data->subdev; tegracam_set_privdata(tc_dev, (void *)priv); - /*Power down gpio enable */ - err = ar0234_enable_pwdn_gpio(tc_dev->s_data); + /* Serializer i2c address trans */ + err = hawk_owl_ser_i2c_trans(tc_dev->s_data); if (err) { dev_err(&client->dev,"Failed to enable gpio/ to do serializer i2c address trans\n"); goto un_register; @@ -1501,13 +1428,11 @@ static int ar0234_probe(struct i2c_client *client, dev_err(&client->dev,"Failed to do EEPROM i2c address trans\n"); goto un_register; } - err = ar0234_board_setup(priv); if (err) { dev_err(dev, "board setup failed\n"); goto release_eeprom; } - /* Un-register i2c client for EEPROM, * so we can re-use i2c address for 2nd sensor of HAWK module */ ar0234_eeprom_device_release(priv); @@ -1518,7 +1443,6 @@ static int ar0234_probe(struct i2c_client *client, dev_err(dev, "failed to do re-i2c address translation\n"); goto un_register; } - /* Set Internal fsync as default mode */ err = Hawk_Owl_Fsync_program(INTERNAL_FSYNC); if (err) { @@ -1545,15 +1469,30 @@ un_register: tegracam_device_unregister(tc_dev); return err; } + +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) static int ar0234_remove(struct i2c_client *client) +#else +static void ar0234_remove(struct i2c_client *client) +#endif { struct camera_common_data *s_data = to_camera_common_data(&client->dev); struct ar0234 *priv = (struct ar0234 *)s_data->priv; + + if (!s_data) +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) + return -EINVAL; +#else + return; +#endif tegracam_v4l2subdev_unregister(priv->tc_dev); tegracam_device_unregister(priv->tc_dev); ar0234_eeprom_device_release(priv); +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) return 0; +#endif } + static const struct i2c_device_id ar0234_id[] = { { "ar0234", 0 }, { } diff --git a/drivers/media/i2c/virtual_i2c_mux.c b/drivers/media/i2c/virtual_i2c_mux.c new file mode 100644 index 00000000..b1b8b4f1 --- /dev/null +++ b/drivers/media/i2c/virtual_i2c_mux.c @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */ +/* + * virtual_i2c_mux.c - virtual i2c mux driver for P3762 & P3783 GMSL boards. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DESER_A (0) +#define ENABLE_IMU (0xFE) +#define ENABLE_ALL_CC (0xAA) +#define DESER_ADDR (0x52) +#define DESER_CC_REG (0x0003) + +extern int max96712_write_reg_Dser(int slaveAddr,int channel, + u16 addr, u8 val); +static int virtual_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + int ret = 0; + + /* Do select 1st channel, to access IMUs from 1st Hawk */ + if (!chan) { + ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_IMU); + if (ret) + pr_err("%s: Failed to do i2c address trans for IMUs\n",__func__); + + } + return ret; +} + +static int virtual_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan) +{ + int ret = 0; + + /* Enable all control channels */ + if (!chan) { + ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_ALL_CC); + if (ret) + pr_err("%s: Failed to do i2c address trans for IMUs\n",__func__); + } + return ret; +} + +#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE +static int virtual_i2c_mux_probe(struct i2c_client *client) +#else +static int virtual_i2c_mux_probe(struct i2c_client *client, + const struct i2c_device_id *id) +#endif +{ + struct device *dev = &client->dev; + struct device_node *np = dev->of_node; + struct device_node *child; + struct i2c_mux_core *muxc; + struct i2c_adapter *parent; + int children; + int ret; + u32 chan; + + dev_info(dev, "probing virtual i2c-mux.\n"); + if (!np) + return -ENODEV; + + parent = client->adapter; + if (IS_ERR(parent)) + return dev_err_probe(dev, PTR_ERR(parent), + "failed to get i2c parent adapter\n"); + + children = of_get_child_count(np); + dev_info(dev, "No of children = %d\n",children); + + muxc = i2c_mux_alloc(parent, dev, children, 0, I2C_MUX_LOCKED, + virtual_i2c_mux_select, virtual_i2c_mux_deselect); + if (!muxc) { + ret = -ENOMEM; + goto err_parent; + } + i2c_set_clientdata(client, muxc); + + for (chan = 0; chan < children; chan++) { + pr_info("%s: chan = %d\n",__func__, chan); + ret = i2c_mux_add_adapter(muxc, 0, chan, 0); + if (ret) + goto err_children; + } + + dev_info(dev, "Probde is successful!!! \n"); + dev_info(dev, "%d-port mux on %s adapter\n", children, parent->name); + + return 0; + +err_children: + of_node_put(child); + i2c_mux_del_adapters(muxc); +err_parent: + i2c_put_adapter(parent); + + return ret; +} + +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) +static int virtual_i2c_mux_remove(struct i2c_client *client) +#else +static void virtual_i2c_mux_remove(struct i2c_client *client) +#endif +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(muxc->parent); +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) + return 0; +#endif +} + +static const struct of_device_id virtual_i2c_mux_of_match[] = { + { .compatible = "nvidia,virtual-i2c-mux", }, + {}, +}; +MODULE_DEVICE_TABLE(of, virtual_i2c_mux_of_match); + +static const struct i2c_device_id virt_i2c_mux_id[] = { + { "virtual-i2c-mux", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, virt_i2c_mux_id); + +static struct i2c_driver virtual_i2c_mux_driver = { + .probe = virtual_i2c_mux_probe, + .remove = virtual_i2c_mux_remove, + .id_table = virt_i2c_mux_id, + .driver = { + .name = "virtual-i2c-mux", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(virtual_i2c_mux_of_match), + }, +}; + +module_i2c_driver(virtual_i2c_mux_driver); + +MODULE_DESCRIPTION("Virtual I2C multiplexer driver"); +MODULE_AUTHOR("Praveen AC "); +MODULE_LICENSE("GPL v2");