t23x:Add virtual i2c mux support & enable IMU.

This change consists of following changes:
1> Add Virtual i2c-mux driver support for P3762.
2> Ser/Dser reg programming to map 1st Hawk's respective MFP's.
   Accel (MFP0) Ser --> Deser (MFP5)
   Gyro (MFP3) Ser --> Deser (MFP7)
3> Disable IMU's for 2nd,3rd & 4th Hawk.
4> Code cleanup.

Bug 4146784

Change-Id: I3f69bd57b1368451d8e2db06366a57b06b5ff0f4
Signed-off-by: Praveen AC <pac@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2971156
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Praveen AC
2023-08-30 16:12:39 +00:00
committed by mobile promotions
parent 8ad7be0833
commit f62619388d
5 changed files with 519 additions and 430 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -11,6 +11,9 @@
#include <linux/debugfs.h>
#include <media/camera_common.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
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;

View File

@@ -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 },
{ }

View File

@@ -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 <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/module.h>
#include <linux/mux/consumer.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/version.h>
#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 <pac@nvidia.com>");
MODULE_LICENSE("GPL v2");