mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
media: add ar0234 sensor driver
Add ar0234 camera sensor driver code, max96712 GMSL serializer code, mode tables and makefile changes. These drivers are copied from K5.10 camera driver repo. Changes include svcacv warning fix and eeprom read status is ignored due to bug 4064490. Bug 3583587 Bug 4064490 Change-Id: I7ea0ecf959caccafd283c8db5fb7c3be912cf8bb Signed-off-by: Ankur Pawar <ankurp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2868422 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
fe2085dcef
commit
c9858e1282
@@ -7,3 +7,5 @@ obj-m += nv_imx185.o
|
||||
obj-m += nv_imx274.o
|
||||
obj-m += nv_imx318.o
|
||||
obj-m += nv_ov5693.o
|
||||
obj-m += max96712.o
|
||||
obj-m += nv_ar0234.o
|
||||
|
||||
699
drivers/media/i2c/ar0234_mode_tbls.h
Normal file
699
drivers/media/i2c/ar0234_mode_tbls.h
Normal file
@@ -0,0 +1,699 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
|
||||
/*
|
||||
* ar0234_mode_tbls.h - ar0234 sensor mode tables
|
||||
*/
|
||||
#ifndef __AR0234_I2C_TABLES__
|
||||
#define __AR0234_I2C_TABLES__
|
||||
|
||||
#include <media/camera_common.h>
|
||||
|
||||
#define AR0234_TABLE_WAIT_MS 0xff00
|
||||
#define AR0234_TABLE_END 0xff01
|
||||
#define AR0234_MAX_RETRIES 3
|
||||
#define AR0234_WAIT_MS_STOP 1
|
||||
#define AR0234_WAIT_MS_START 30
|
||||
#define AR0234_WAIT_MS_STREAM 210
|
||||
#define AR0234_GAIN_TABLE_SIZE 255
|
||||
|
||||
#define AR0234_EEPROM_ADDRESS 0x54
|
||||
#define AR0234_EEPROM_ADDRESS_R 0x58
|
||||
#define AR0234_EEPROM_SIZE 512
|
||||
#define AR0234_EEPROM_STR_SIZE (AR0234_EEPROM_SIZE * 2)
|
||||
#define AR0234_EEPROM_BLOCK_SIZE (1 << 8)
|
||||
#define AR0234_EEPROM_NUM_BLOCKS \
|
||||
(AR0234_EEPROM_SIZE / AR0234_EEPROM_BLOCK_SIZE)
|
||||
|
||||
|
||||
#define ar0234_reg struct reg_16
|
||||
|
||||
struct index_reg_8 {
|
||||
u16 source;
|
||||
u16 addr;
|
||||
u16 val;
|
||||
};
|
||||
|
||||
static struct index_reg_8 ar0234_start[] = {
|
||||
{0x06, 0x30ce, 0x0120},
|
||||
{0x06, 0x301A, 0x295C}, // RESET_REGISTER
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00}
|
||||
};
|
||||
|
||||
static struct index_reg_8 ar0234_stop[] = {
|
||||
{0x06, 0x301a, 0x2058},
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00}
|
||||
};
|
||||
|
||||
static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
|
||||
{0x52, 0x1458, 0x28},
|
||||
{0x52, 0x1459, 0x68},
|
||||
{0x52, 0x1558, 0x28},
|
||||
{0x52, 0x1559, 0x68},
|
||||
{0x52, 0x1658, 0x28},
|
||||
{0x52, 0x1659, 0x68},
|
||||
{0x52, 0x1758, 0x28},
|
||||
{0x52, 0x1759, 0x68},
|
||||
|
||||
{0x52, 0x0018, 0x0F}, // Oneshot reset
|
||||
{0x52, 0x0006, 0xF3}, // Enable links A and B
|
||||
{0x52, 0x0001, 0xcc}, // disable the i2c2
|
||||
|
||||
{0x52, 0x0003, 0xAE}, // Disable CC to link B
|
||||
{0x80, 0x0000, 0x84}, // Link A serializer address is 0x84
|
||||
|
||||
{0x52, 0x0003, 0xAB}, // Disable CC to link A
|
||||
{0x80, 0x0000, 0x88}, // Link B serializer address is 0x88
|
||||
{0x52, 0x0003, 0xAA}, // Enable CC to links A and B
|
||||
{0x84, 0x0002, 0x33}, // Enable pipes X and Y
|
||||
{0x84, 0x0308, 0x7E}, // Pipe X pulls clock from port A, pipe Y from port B
|
||||
{0x84, 0x0311, 0x21}, // Pipe X pulls data from port A, pipe Y from port B
|
||||
{0x84, 0x0316, 0x6b}, // RAW10 to pipe Y
|
||||
{0x84, 0x0314, 0x6b}, // RAW10 to pipe Y
|
||||
{0x88, 0x0002, 0x33}, // Enable pipes X and Y
|
||||
{0x88, 0x0308, 0x7E}, // Pipe X pulls clock from port A, pipe Y from port B
|
||||
{0x88, 0x0311, 0x21}, // Pipe X pulls data from port A, pipe Y from port B
|
||||
{0x88, 0x0316, 0x6b}, // RAW10 to pipe Y
|
||||
{0x88, 0x0314, 0x6b}, // RAW10 to pipe Y
|
||||
{0x52, 0x00F4, 0x0f}, // Enable pipe 0
|
||||
{0x52, 0x00F0, 0x10}, // Link A ID 0 to pipe 0 // Link A ID 1 to pipe 1
|
||||
{0x52, 0x00F1, 0x54}, // Link B ID 0 to pipe 2 // Link B ID 1 to pipe 3
|
||||
|
||||
{0x52, 0x08A0, 0x01}, // CSI output is 2x4
|
||||
{0x52, 0x08A3, 0x44}, // Default 4x2 lane mapping
|
||||
{0x52, 0x08A4, 0x44}, // Default 4x2 lane mapping
|
||||
|
||||
{0x52, 0x090A, 0x40},
|
||||
{0x52, 0x094A, 0x40}, // 2 lanes on port D
|
||||
{0x52, 0x098A, 0x40}, // 2 lanes on port E
|
||||
{0x52, 0x09CA, 0x40},
|
||||
|
||||
{0x52, 0x1D00, 0xF4},
|
||||
{0x52, 0x1E00, 0xF4},
|
||||
|
||||
{0x52, 0x0415, 0x2E},
|
||||
{0x52, 0x0418, 0x2E}, // 1400Mbps
|
||||
{0x52, 0x041B, 0x2E},
|
||||
{0x52, 0x041E, 0x2E},
|
||||
|
||||
{0x52, 0x1D00, 0xF5},
|
||||
{0x52, 0x1E00, 0xF5},
|
||||
|
||||
{0x52, 0x090B, 0x07}, // Enable 3 mappings Pipe 0//video2
|
||||
{0x52, 0x092D, 0x15}, // All mappings to controller 1 (port A)
|
||||
{0x52, 0x090D, 0x2B}, // Input RAW10, VC0
|
||||
{0x52, 0x090E, 0x2B}, // Output RAW10, VC0
|
||||
{0x52, 0x090F, 0x00}, // Input FS, VC0
|
||||
{0x52, 0x0910, 0x00}, // Output FS, VC0
|
||||
{0x52, 0x0911, 0x01}, // Input FE, VC0
|
||||
{0x52, 0x0912, 0x01}, // Output FE, VC0
|
||||
|
||||
{0x52, 0x094B, 0x07}, // Enable 3 mappings Pipe 1 //video3
|
||||
{0x52, 0x096D, 0x15}, // All mappings to controller 1 (port A)
|
||||
{0x52, 0x094D, 0x2B}, // Input RAW10, VC0
|
||||
{0x52, 0x094E, 0x6B}, // Output RAW10, VC1
|
||||
{0x52, 0x094F, 0x00}, // Input FS, VC0
|
||||
{0x52, 0x0950, 0x40}, // Output FS, VC1
|
||||
{0x52, 0x0951, 0x01}, // Input FE, VC0
|
||||
{0x52, 0x0952, 0x41}, // Output FE, VC1
|
||||
|
||||
{0x52, 0x098B, 0x07}, // Enable 3 mappings Pipe 2 //video1
|
||||
{0x52, 0x09AD, 0x15}, // All mappings to controller 1 (port A)
|
||||
{0x52, 0x098D, 0x2B}, // Input RAW10, VC0
|
||||
{0x52, 0x098E, 0xaB}, // Output RAW10, VC2
|
||||
{0x52, 0x098F, 0x00}, // Input FS, VC0
|
||||
{0x52, 0x0990, 0x80}, // Output FS, VC2
|
||||
{0x52, 0x0991, 0x01}, // Input FE, VC0
|
||||
{0x52, 0x0992, 0x81}, // Output FE, VC2
|
||||
|
||||
{0x52, 0x09CB, 0x07}, // Enable 3 mappings Pipe 3 //video0
|
||||
{0x52, 0x09ED, 0x15}, // All mappings to controller 1 (port A)
|
||||
{0x52, 0x09CD, 0x2B}, // Input RAW10, VC0
|
||||
{0x52, 0x09CE, 0xeB}, // Output RAW10, VC3
|
||||
{0x52, 0x09CF, 0x00}, // Input FS, VC0
|
||||
{0x52, 0x09D0, 0xc0}, // Output FS, VC3
|
||||
{0x52, 0x09D1, 0x01}, // Input FE, VC0
|
||||
{0x52, 0x09D2, 0xc1}, // Output FE, VC3
|
||||
|
||||
{0x52, 0x08A2, 0xF0},
|
||||
{0x84, 0x02be, 0x90}, // Enable sensor power down pin.
|
||||
{0x84, 0x02bf, 0x60}, // Enable sensor reset pin.
|
||||
{0x84, 0x02ca, 0x80}, // Enable sensor power down pin.
|
||||
{0x84, 0x02cb, 0x60}, // Enable sensor reset pin.
|
||||
{0x84, 0x02d3, 0x90}, // Enable sensor power down pin.
|
||||
{0x84, 0x02d4, 0x60}, // Enable sensor reset pin.
|
||||
{0x84, 0x02d6, 0x90}, // Enable sensor power down pin.
|
||||
{0x84, 0x02d7, 0x60}, // Enable sensor reset pin.
|
||||
{0x88, 0x02be, 0x90}, // Enable sensor power down pin.
|
||||
{0x88, 0x02bf, 0x60}, // Enable sensor reset pin.
|
||||
{0x88, 0x02ca, 0x80}, // Enable sensor power down pin.
|
||||
{0x88, 0x02cb, 0x60}, // Enable sensor reset pin.
|
||||
{0x88, 0x02d3, 0x90}, // Enable sensor power down pin.
|
||||
{0x88, 0x02d4, 0x60}, // Enable sensor reset pin.
|
||||
{0x88, 0x02d6, 0x90}, // Enable sensor power down pin.
|
||||
{0x88, 0x02d7, 0x60}, // Enable sensor reset pin.
|
||||
|
||||
|
||||
{0x52, 0x04AF, 0xC0}, // AUTO_FS_LINKS = 0, FS_USE_XTAL = 1, FS_LINK_[3:0] = 0
|
||||
{0x52, 0x04A0, 0x00}, // Manual frame sync, no pin output
|
||||
|
||||
{0x52, 0x04A2, 0x00}, // Turn off auto master link selection
|
||||
{0x52, 0x04AA, 0x00}, // OVLP window = 0
|
||||
{0x52, 0x04AB, 0x00},
|
||||
|
||||
{0x52, 0x04A5, 0x35}, // 30Hz FSYNC
|
||||
{0x52, 0x04A6, 0xB7},
|
||||
{0x52, 0x04A7, 0x0C},
|
||||
|
||||
{0x84, 0x02D9, 0x04},
|
||||
{0x84, 0x02DB, 0x08},
|
||||
{0x84, 0x02Dc, 0x04},
|
||||
{0x84, 0x02De, 0x08}, // MFP8 for FSIN
|
||||
|
||||
{0x88, 0x02D9, 0x04},
|
||||
{0x88, 0x02DB, 0x08},
|
||||
{0x88, 0x02Dc, 0x04},
|
||||
{0x88, 0x02De, 0x08}, // MFP8 for FSIN
|
||||
|
||||
{0x52, 0x04B1, 0x40}, // FSYNC TX ID is 8
|
||||
|
||||
{0x84, 0x0042, 0xB0}, // eeprom i2c map
|
||||
{0x84, 0x0043, 0xA8},
|
||||
{0x84, 0x0044, 0xB2},
|
||||
{0x84, 0x0045, 0xAA},
|
||||
|
||||
{0x88, 0x0042, 0xB0}, // eeprom i2c map
|
||||
{0x88, 0x0043, 0xA8},
|
||||
{0x88, 0x0044, 0xB2},
|
||||
{0x88, 0x0045, 0xAA},
|
||||
|
||||
{0x84, 0x02be, 0x83}, // hawk1(0x84) max9295D MFP0-- ACCEL interrupt
|
||||
{0x84, 0x02bf, 0x11},
|
||||
{0x52, 0x030c, 0x04}, // max96712 MTF4---ACCEL1 interrupt
|
||||
{0x52, 0x030e, 0x11}, // MTF4
|
||||
|
||||
{0x84, 0x02c7, 0x83}, // hawk1(0x84)max9295D MFP3-- gyro interrupt
|
||||
{0x84, 0x02c8, 0x12},
|
||||
{0x52, 0x0320, 0x04}, // max96712 MTF10---gyro1 interrupt
|
||||
{0x52, 0x0322, 0x12}, // MTF10
|
||||
|
||||
// Disable output, enable TX hawk2(0x88) max9295D MFP0-- ACCEL interrupt
|
||||
{0x88, 0x02BE, 0x03},
|
||||
{0x88, 0x02BF, 0x00}, // No pull-up/down, TX ID = 0
|
||||
{0x52, 0x0310, 0x00}, // Enable output max96712 MTF5---ACCEL2 interrupt
|
||||
{0x52, 0x0347, 0x05}, // Disable TX on link B
|
||||
{0x52, 0x0348, 0x60}, // Enable RX on link B, RX ID = 0
|
||||
|
||||
{0x88, 0x02c7, 0x03}, // hawk2(0x88)max9295D MFP3-- gyro interrupt
|
||||
{0x88, 0x02c8, 0x15},
|
||||
{0x52, 0x0313, 0x00},
|
||||
{0x52, 0x034A, 0x05}, // max96712 MTF6---gyro2 interrupt
|
||||
{0x52, 0x034B, 0x75}, // MTF6
|
||||
|
||||
{0x52, 0x0003, 0xFF}, // enable i2c channel B
|
||||
{0x52, 0x0007, 0x20},
|
||||
{0x52, 0x0003, 0xF6},
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct index_reg_8 ar0234_Single_Dser_Ser[] = {
|
||||
{0x52, 0x1458, 0x28},
|
||||
{0x52, 0x1459, 0x68},
|
||||
{0x52, 0x1558, 0x28},
|
||||
{0x52, 0x1559, 0x68},
|
||||
{0x52, 0x1658, 0x28},
|
||||
{0x52, 0x1659, 0x68},
|
||||
{0x52, 0x1758, 0x28},
|
||||
{0x52, 0x1759, 0x68},
|
||||
|
||||
{0x52, 0x0018, 0x0F},
|
||||
{0x52, 0x0006, 0xF1},
|
||||
{0x52, 0x0001, 0xcc}, // disable the i2c2
|
||||
{0x80, 0x0010, 0x21},
|
||||
{0x80, 0x0330, 0x06},
|
||||
{0x80, 0x0332, 0x4E},
|
||||
{0x80, 0x0333, 0xE4},
|
||||
{0x80, 0x0331, 0x77},
|
||||
{0x80, 0x0311, 0x41},
|
||||
{0x80, 0x0308, 0x74},
|
||||
{0x80, 0x0314, 0x2B},
|
||||
{0x80, 0x0316, 0x22},
|
||||
{0x80, 0x0318, 0x2B},
|
||||
{0x80, 0x031A, 0x22},
|
||||
{0x80, 0x0002, 0xff},
|
||||
{0x80, 0x0053, 0x10},
|
||||
{0x80, 0x0057, 0x11},
|
||||
{0x80, 0x005B, 0x12},
|
||||
{0x80, 0x005F, 0x13},
|
||||
|
||||
{0x52, 0x00F0, 0x20}, // pipx--pip0 pipz--pip1 gmsl phy A
|
||||
|
||||
{0x52, 0x00F4, 0x03}, // enable pip 0/1
|
||||
|
||||
{0x52, 0x08A0, 0x01},
|
||||
{0x52, 0x08A3, 0x44},
|
||||
{0x52, 0x08A4, 0x44},
|
||||
{0x52, 0x090A, 0x40},
|
||||
{0x52, 0x094A, 0x40},
|
||||
{0x52, 0x098A, 0x40},
|
||||
{0x52, 0x09CA, 0x40},
|
||||
{0x52, 0x0415, 0x2E},
|
||||
{0x52, 0x0418, 0x2E},
|
||||
{0x52, 0x041B, 0x2E},
|
||||
{0x52, 0x041E, 0x2E},
|
||||
|
||||
{0x52, 0x090B, 0x07},
|
||||
{0x52, 0x092D, 0x15},
|
||||
{0x52, 0x090D, 0x2b},
|
||||
{0x52, 0x090E, 0x2b},
|
||||
{0x52, 0x090F, 0x00},
|
||||
{0x52, 0x0910, 0x00},
|
||||
{0x52, 0x0911, 0x01},
|
||||
{0x52, 0x0912, 0x01},
|
||||
|
||||
{0x52, 0x094B, 0x07},
|
||||
{0x52, 0x096D, 0x15},
|
||||
{0x52, 0x094D, 0x2b},
|
||||
{0x52, 0x094E, 0x6b},
|
||||
{0x52, 0x094F, 0x00},
|
||||
{0x52, 0x0950, 0x40},
|
||||
{0x52, 0x0951, 0x01},
|
||||
{0x52, 0x0952, 0x41},
|
||||
|
||||
{0x80, 0x02be, 0x90}, // Enable sensor power down pin.
|
||||
{0x80, 0x02bf, 0x60}, // Enable sensor reset pin.
|
||||
{0x80, 0x02ca, 0x80}, // Enable sensor power down pin.
|
||||
{0x80, 0x02cb, 0x60}, // Enable sensor reset pin.
|
||||
{0x80, 0x02d3, 0x90}, // Enable sensor power down pin.
|
||||
{0x80, 0x02d4, 0x60}, // Enable sensor reset pin.
|
||||
{0x80, 0x02d6, 0x90}, // Enable sensor power down pin.
|
||||
{0x80, 0x02d7, 0x60}, // Enable sensor reset pin.
|
||||
|
||||
{0x52, 0x04AF, 0xC0}, // AUTO_FS_LINKS = 0, FS_USE_XTAL = 1, FS_LINK_[3:0] = 0
|
||||
{0x52, 0x04A0, 0x04}, // Manual frame sync, output on MFP2
|
||||
{0x52, 0x04A2, 0x00}, // Turn off auto master link selection
|
||||
{0x52, 0x04AA, 0x00}, // OVLP window = 0
|
||||
{0x52, 0x04AB, 0x00},
|
||||
{0x52, 0x04A5, 0x35}, // 30Hz FSYNC
|
||||
{0x52, 0x04A6, 0xB7},
|
||||
{0x52, 0x04A7, 0x0C},
|
||||
|
||||
{0x80, 0x02D9, 0x04},
|
||||
{0x80, 0x02DB, 0x08}, // MFP8 for FSIN
|
||||
{0x80, 0x02Dc, 0x04},
|
||||
{0x80, 0x02De, 0x08}, // MFP8 for FSIN
|
||||
{0x52, 0x04B1, 0x40}, // FSYNC TX ID is 8
|
||||
|
||||
{0x80, 0x0042, 0xB0}, // eeprom i2c map eeporm have two i2c address
|
||||
{0x80, 0x0043, 0xA8},
|
||||
{0x80, 0x0044, 0xB2},
|
||||
{0x80, 0x0045, 0xAA},
|
||||
|
||||
{0x80, 0x02be, 0x83}, // hawk1(0x84) max9295D MFP0-- ACCEL interrupt
|
||||
{0x80, 0x02bf, 0x11},
|
||||
{0x52, 0x030c, 0x04}, // max96712 MTF4---ACCEL1 interrupt
|
||||
{0x52, 0x030e, 0x11}, // MTF4
|
||||
|
||||
{0x80, 0x02c7, 0x83}, // hawk1(0x84)max9295D MFP3-- gyro interrupt
|
||||
{0x80, 0x02c8, 0x12},
|
||||
{0x52, 0x0320, 0x04}, // max96712 MTF10---gyro1 interrupt
|
||||
{0x52, 0x0322, 0x12}, // MTF10
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00 }
|
||||
};
|
||||
|
||||
static struct index_reg_8 ar0234_1920x1080_crop_30fps[] = {
|
||||
{0x06, 0x301A, 0x00D9},
|
||||
{0x06, AR0234_TABLE_WAIT_MS, 100},
|
||||
|
||||
{0x06, 0x3F4C, 0x121F},
|
||||
{0x06, 0x3F4E, 0x121F},
|
||||
{0x06, 0x3F50, 0x0B81},
|
||||
{0x06, 0x31E0, 0x0003},
|
||||
{0x06, 0x31E0, 0x0003},
|
||||
{0x06, 0x30B0, 0x0028},
|
||||
{0x06, 0x3088, 0x8000},
|
||||
{0x06, 0x3086, 0xC1AE},
|
||||
{0x06, 0x3086, 0x327F},
|
||||
{0x06, 0x3086, 0x5780},
|
||||
{0x06, 0x3086, 0x272F},
|
||||
{0x06, 0x3086, 0x7416},
|
||||
{0x06, 0x3086, 0x7E13},
|
||||
{0x06, 0x3086, 0x8000},
|
||||
{0x06, 0x3086, 0x307E},
|
||||
{0x06, 0x3086, 0xFF80},
|
||||
{0x06, 0x3086, 0x20C3},
|
||||
{0x06, 0x3086, 0xB00E},
|
||||
{0x06, 0x3086, 0x8190},
|
||||
{0x06, 0x3086, 0x1643},
|
||||
{0x06, 0x3086, 0x1651},
|
||||
{0x06, 0x3086, 0x9D3E},
|
||||
{0x06, 0x3086, 0x9545},
|
||||
{0x06, 0x3086, 0x2209},
|
||||
{0x06, 0x3086, 0x3781},
|
||||
{0x06, 0x3086, 0x9016},
|
||||
{0x06, 0x3086, 0x4316},
|
||||
{0x06, 0x3086, 0x7F90},
|
||||
{0x06, 0x3086, 0x8000},
|
||||
{0x06, 0x3086, 0x387F},
|
||||
{0x06, 0x3086, 0x1380},
|
||||
{0x06, 0x3086, 0x233B},
|
||||
{0x06, 0x3086, 0x7F93},
|
||||
{0x06, 0x3086, 0x4502},
|
||||
{0x06, 0x3086, 0x8000},
|
||||
{0x06, 0x3086, 0x7FB0},
|
||||
{0x06, 0x3086, 0x8D66},
|
||||
{0x06, 0x3086, 0x7F90},
|
||||
{0x06, 0x3086, 0x8192},
|
||||
{0x06, 0x3086, 0x3C16},
|
||||
{0x06, 0x3086, 0x357F},
|
||||
{0x06, 0x3086, 0x9345},
|
||||
{0x06, 0x3086, 0x0280},
|
||||
{0x06, 0x3086, 0x007F},
|
||||
{0x06, 0x3086, 0xB08D},
|
||||
{0x06, 0x3086, 0x667F},
|
||||
{0x06, 0x3086, 0x9081},
|
||||
{0x06, 0x3086, 0x8237},
|
||||
{0x06, 0x3086, 0x4502},
|
||||
{0x06, 0x3086, 0x3681},
|
||||
{0x06, 0x3086, 0x8044},
|
||||
{0x06, 0x3086, 0x1631},
|
||||
{0x06, 0x3086, 0x4374},
|
||||
{0x06, 0x3086, 0x1678},
|
||||
{0x06, 0x3086, 0x7B7D},
|
||||
{0x06, 0x3086, 0x4502},
|
||||
{0x06, 0x3086, 0x450A},
|
||||
{0x06, 0x3086, 0x7E12},
|
||||
{0x06, 0x3086, 0x8180},
|
||||
{0x06, 0x3086, 0x377F},
|
||||
{0x06, 0x3086, 0x1045},
|
||||
{0x06, 0x3086, 0x0A0E},
|
||||
{0x06, 0x3086, 0x7FD4},
|
||||
{0x06, 0x3086, 0x8024},
|
||||
{0x06, 0x3086, 0x0E82},
|
||||
{0x06, 0x3086, 0x9CC2},
|
||||
{0x06, 0x3086, 0xAFA8},
|
||||
{0x06, 0x3086, 0xAA03},
|
||||
{0x06, 0x3086, 0x430D},
|
||||
{0x06, 0x3086, 0x2D46},
|
||||
{0x06, 0x3086, 0x4316},
|
||||
{0x06, 0x3086, 0x5F16},
|
||||
{0x06, 0x3086, 0x530D},
|
||||
{0x06, 0x3086, 0x1660},
|
||||
{0x06, 0x3086, 0x401E},
|
||||
{0x06, 0x3086, 0x2904},
|
||||
{0x06, 0x3086, 0x2984},
|
||||
{0x06, 0x3086, 0x81E7},
|
||||
{0x06, 0x3086, 0x816F},
|
||||
{0x06, 0x3086, 0x1706},
|
||||
{0x06, 0x3086, 0x81E7},
|
||||
{0x06, 0x3086, 0x7F81},
|
||||
{0x06, 0x3086, 0x5C0D},
|
||||
{0x06, 0x3086, 0x5754},
|
||||
{0x06, 0x3086, 0x495F},
|
||||
{0x06, 0x3086, 0x5305},
|
||||
{0x06, 0x3086, 0x5307},
|
||||
{0x06, 0x3086, 0x4D2B},
|
||||
{0x06, 0x3086, 0xF810},
|
||||
{0x06, 0x3086, 0x164C},
|
||||
{0x06, 0x3086, 0x0755},
|
||||
{0x06, 0x3086, 0x562B},
|
||||
{0x06, 0x3086, 0xB82B},
|
||||
{0x06, 0x3086, 0x984E},
|
||||
{0x06, 0x3086, 0x1129},
|
||||
{0x06, 0x3086, 0x9460},
|
||||
{0x06, 0x3086, 0x5C09},
|
||||
{0x06, 0x3086, 0x5C1B},
|
||||
{0x06, 0x3086, 0x4002},
|
||||
{0x06, 0x3086, 0x4500},
|
||||
{0x06, 0x3086, 0x4580},
|
||||
{0x06, 0x3086, 0x29B6},
|
||||
{0x06, 0x3086, 0x7F80},
|
||||
{0x06, 0x3086, 0x4004},
|
||||
{0x06, 0x3086, 0x7F88},
|
||||
{0x06, 0x3086, 0x4109},
|
||||
{0x06, 0x3086, 0x5C0B},
|
||||
{0x06, 0x3086, 0x29B2},
|
||||
{0x06, 0x3086, 0x4115},
|
||||
{0x06, 0x3086, 0x5C03},
|
||||
{0x06, 0x3086, 0x4105},
|
||||
{0x06, 0x3086, 0x5F2B},
|
||||
{0x06, 0x3086, 0x902B},
|
||||
{0x06, 0x3086, 0x8081},
|
||||
{0x06, 0x3086, 0x6F40},
|
||||
{0x06, 0x3086, 0x1041},
|
||||
{0x06, 0x3086, 0x0160},
|
||||
{0x06, 0x3086, 0x29A2},
|
||||
{0x06, 0x3086, 0x29A3},
|
||||
{0x06, 0x3086, 0x5F4D},
|
||||
{0x06, 0x3086, 0x1C17},
|
||||
{0x06, 0x3086, 0x0281},
|
||||
{0x06, 0x3086, 0xE729},
|
||||
{0x06, 0x3086, 0x8345},
|
||||
{0x06, 0x3086, 0x8840},
|
||||
{0x06, 0x3086, 0x0F7F},
|
||||
{0x06, 0x3086, 0x8A40},
|
||||
{0x06, 0x3086, 0x2345},
|
||||
{0x06, 0x3086, 0x8024},
|
||||
{0x06, 0x3086, 0x4008},
|
||||
{0x06, 0x3086, 0x7F88},
|
||||
{0x06, 0x3086, 0x5D29},
|
||||
{0x06, 0x3086, 0x9288},
|
||||
{0x06, 0x3086, 0x102B},
|
||||
{0x06, 0x3086, 0x0489},
|
||||
{0x06, 0x3086, 0x165C},
|
||||
{0x06, 0x3086, 0x4386},
|
||||
{0x06, 0x3086, 0x170B},
|
||||
{0x06, 0x3086, 0x5C03},
|
||||
{0x06, 0x3086, 0x8A48},
|
||||
{0x06, 0x3086, 0x4D4E},
|
||||
{0x06, 0x3086, 0x2B80},
|
||||
{0x06, 0x3086, 0x4C09},
|
||||
{0x06, 0x3086, 0x4119},
|
||||
{0x06, 0x3086, 0x816F},
|
||||
{0x06, 0x3086, 0x4110},
|
||||
{0x06, 0x3086, 0x4001},
|
||||
{0x06, 0x3086, 0x6029},
|
||||
{0x06, 0x3086, 0x8229},
|
||||
{0x06, 0x3086, 0x8329},
|
||||
{0x06, 0x3086, 0x435C},
|
||||
{0x06, 0x3086, 0x055F},
|
||||
{0x06, 0x3086, 0x4D1C},
|
||||
{0x06, 0x3086, 0x81E7},
|
||||
{0x06, 0x3086, 0x4502},
|
||||
{0x06, 0x3086, 0x8180},
|
||||
{0x06, 0x3086, 0x7F80},
|
||||
{0x06, 0x3086, 0x410A},
|
||||
{0x06, 0x3086, 0x9144},
|
||||
{0x06, 0x3086, 0x1609},
|
||||
{0x06, 0x3086, 0x2FC3},
|
||||
{0x06, 0x3086, 0xB130},
|
||||
{0x06, 0x3086, 0xC3B1},
|
||||
{0x06, 0x3086, 0x0343},
|
||||
{0x06, 0x3086, 0x164A},
|
||||
{0x06, 0x3086, 0x0A43},
|
||||
{0x06, 0x3086, 0x160B},
|
||||
{0x06, 0x3086, 0x4316},
|
||||
{0x06, 0x3086, 0x8F43},
|
||||
{0x06, 0x3086, 0x1690},
|
||||
{0x06, 0x3086, 0x4316},
|
||||
{0x06, 0x3086, 0x7F81},
|
||||
{0x06, 0x3086, 0x450A},
|
||||
{0x06, 0x3086, 0x410F},
|
||||
{0x06, 0x3086, 0x7F83},
|
||||
{0x06, 0x3086, 0x5D29},
|
||||
{0x06, 0x3086, 0x4488},
|
||||
{0x06, 0x3086, 0x102B},
|
||||
{0x06, 0x3086, 0x0453},
|
||||
{0x06, 0x3086, 0x0D40},
|
||||
{0x06, 0x3086, 0x2345},
|
||||
{0x06, 0x3086, 0x0240},
|
||||
{0x06, 0x3086, 0x087F},
|
||||
{0x06, 0x3086, 0x8053},
|
||||
{0x06, 0x3086, 0x0D89},
|
||||
{0x06, 0x3086, 0x165C},
|
||||
{0x06, 0x3086, 0x4586},
|
||||
{0x06, 0x3086, 0x170B},
|
||||
{0x06, 0x3086, 0x5C05},
|
||||
{0x06, 0x3086, 0x8A60},
|
||||
{0x06, 0x3086, 0x4B91},
|
||||
{0x06, 0x3086, 0x4416},
|
||||
{0x06, 0x3086, 0x09C1},
|
||||
{0x06, 0x3086, 0x2CA9},
|
||||
{0x06, 0x3086, 0xAB30},
|
||||
{0x06, 0x3086, 0x51B3},
|
||||
{0x06, 0x3086, 0x3D5A},
|
||||
{0x06, 0x3086, 0x7E3D},
|
||||
{0x06, 0x3086, 0x7E19},
|
||||
{0x06, 0x3086, 0x8000},
|
||||
{0x06, 0x3086, 0x8B1F},
|
||||
{0x06, 0x3086, 0x2A1F},
|
||||
{0x06, 0x3086, 0x83A2},
|
||||
{0x06, 0x3086, 0x7516},
|
||||
{0x06, 0x3086, 0xAD33},
|
||||
{0x06, 0x3086, 0x450A},
|
||||
{0x06, 0x3086, 0x7F53},
|
||||
{0x06, 0x3086, 0x8023},
|
||||
{0x06, 0x3086, 0x8C66},
|
||||
{0x06, 0x3086, 0x7F13},
|
||||
{0x06, 0x3086, 0x8184},
|
||||
{0x06, 0x3086, 0x1481},
|
||||
{0x06, 0x3086, 0x8031},
|
||||
{0x06, 0x3086, 0x3D64},
|
||||
{0x06, 0x3086, 0x452A},
|
||||
{0x06, 0x3086, 0x9451},
|
||||
{0x06, 0x3086, 0x9E96},
|
||||
{0x06, 0x3086, 0x3D2B},
|
||||
{0x06, 0x3086, 0x3D1B},
|
||||
{0x06, 0x3086, 0x529F},
|
||||
{0x06, 0x3086, 0x0E3D},
|
||||
{0x06, 0x3086, 0x083D},
|
||||
{0x06, 0x3086, 0x167E},
|
||||
{0x06, 0x3086, 0x307E},
|
||||
{0x06, 0x3086, 0x1175},
|
||||
{0x06, 0x3086, 0x163E},
|
||||
{0x06, 0x3086, 0x970E},
|
||||
{0x06, 0x3086, 0x82B2},
|
||||
{0x06, 0x3086, 0x3D7F},
|
||||
{0x06, 0x3086, 0xAC3E},
|
||||
{0x06, 0x3086, 0x4502},
|
||||
{0x06, 0x3086, 0x7E11},
|
||||
{0x06, 0x3086, 0x7FD0},
|
||||
{0x06, 0x3086, 0x8000},
|
||||
{0x06, 0x3086, 0x8C66},
|
||||
{0x06, 0x3086, 0x7F90},
|
||||
{0x06, 0x3086, 0x8194},
|
||||
{0x06, 0x3086, 0x3F44},
|
||||
{0x06, 0x3086, 0x1681},
|
||||
{0x06, 0x3086, 0x8416},
|
||||
{0x06, 0x3086, 0x2C2C},
|
||||
{0x06, 0x3086, 0x2C2C},
|
||||
{0x06, 0x302A, 0x0005},
|
||||
{0x06, 0x302C, 0x0001},
|
||||
{0x06, 0x302E, 0x0003},
|
||||
{0x06, 0x3030, 0x0096}, // PLL multiplier
|
||||
{0x06, 0x302E, 0x0006}, // PLL input pre-divider value
|
||||
{0x06, 0x302C, 0x0004}, // P1 divider
|
||||
{0x06, 0x302A, 0x0005}, // P2 divider
|
||||
{0x06, 0x3038, 0x0004}, // P3 divider
|
||||
{0x06, 0x3036, 0x000A}, // WCD divider
|
||||
{0x06, 0x31B0, 0x002F}, // Frame preamble
|
||||
{0x06, 0x31B2, 0x002C}, // Line preamble
|
||||
{0x06, 0x31B4, 0x1144}, // MIPI timing 0
|
||||
{0x06, 0x31B6, 0x00C7}, // MIPI timing 1
|
||||
{0x06, 0x31B8, 0x3047}, // MIPI timing 2
|
||||
{0x06, 0x31BA, 0x0103}, // MIPI timing 3
|
||||
{0x06, 0x31BC, 0x8583}, // MIPI timing 4
|
||||
{0x06, 0x31AE, 0x0204}, // 4-lane MIPI
|
||||
{0x06, 0x3002, 0x0008}, // Y_ADDR_START = 8
|
||||
{0x06, 0x3004, 0x0008}, // X_ADDR_START = 8
|
||||
{0x06, 0x3006, 0x04B7}, // Y_ADDR_END = 1207
|
||||
{0x06, 0x3008, 0x0787}, // X_ADDR_END = 1927
|
||||
{0x06, 0x300A, 0x04C6}, // FRAME_LENGTH_LINES = 1220
|
||||
{0x06, 0x300C, 0x0264}, // LINE_LENGTH_PCK = 612
|
||||
{0x06, 0x3012, 0x02DC}, // COARSE_INTEGRATION_TIME = 732
|
||||
{0x06, 0x31AC, 0x0A0A}, // DATA_FORMAT_BITS = 2570
|
||||
{0x06, 0x306E, 0x9010}, // DATAPATH_SELECT = 36880
|
||||
{0x06, 0x30A2, 0x0001}, // X_ODD_INC = 1
|
||||
{0x06, 0x30A6, 0x0001}, // Y_ODD_INC = 1
|
||||
{0x06, 0x3082, 0x0003}, // OPERATION_MODE_CTRL = 3
|
||||
{0x06, 0x3040, 0x0000}, // READ_MODE = 0
|
||||
{0x06, 0x31D0, 0x0000}, // COMPANDING = 0
|
||||
|
||||
{0x06, 0x3044, 0x0410},
|
||||
{0x06, 0x3094, 0x03D4},
|
||||
{0x06, 0x3096, 0x0480},
|
||||
{0x06, 0x30BA, 0x7602},
|
||||
{0x06, 0x30B0, 0x0028},
|
||||
{0x06, 0x30FE, 0x002A},
|
||||
{0x06, 0x31DE, 0x0410},
|
||||
{0x06, 0x3ED6, 0x1435},
|
||||
{0x06, 0x3ED8, 0x9865},
|
||||
{0x06, 0x3EDA, 0x7698},
|
||||
{0x06, 0x3EDC, 0x99FF},
|
||||
{0x06, 0x3EE2, 0xBB88},
|
||||
{0x06, 0x3EE4, 0x8836},
|
||||
{0x06, 0x3EF0, 0x1CF0},
|
||||
{0x06, 0x3EF2, 0x0000},
|
||||
{0x06, 0x3EF8, 0x6166},
|
||||
{0x06, 0x3EFA, 0x3333},
|
||||
{0x06, 0x3EFC, 0x6634},
|
||||
{0x06, 0x3276, 0x05DC},
|
||||
{0x06, 0x3F00, 0x9D05},
|
||||
{0x06, 0x3ED2, 0xFA86},
|
||||
{0x06, 0x3EEE, 0xA4FE},
|
||||
{0x06, 0x30BA, 0x7602},
|
||||
{0x06, 0x3180, 0xC24F},
|
||||
{0x06, 0x3ECC, 0x6E42},
|
||||
{0x06, 0x3ECC, 0x0E42},
|
||||
{0x06, 0x3EEC, 0x0C0C},
|
||||
{0x06, 0x3EE8, 0xAAE4},
|
||||
{0x06, 0x3EE6, 0x3363},
|
||||
{0x06, 0x3EE6, 0x3363},
|
||||
{0x06, 0x3EE8, 0xAAE4},
|
||||
{0x06, 0x3EE8, 0xAAE4},
|
||||
{0x06, 0x3102, 0x5000},
|
||||
{0x06, 0x3060, 0x000D},
|
||||
{0x06, 0x3ED0, 0xFF44},
|
||||
{0x06, 0x3ED2, 0xAA86},
|
||||
{0x06, 0x3ED4, 0x031F},
|
||||
{0x06, 0x3EEE, 0xA4AA},
|
||||
{0x06, 0x301a, 0x2058},
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00},
|
||||
};
|
||||
|
||||
static struct index_reg_8 tp_colorbars[] = {
|
||||
{0x06, 0x3070, 0x2},
|
||||
|
||||
{0x00, AR0234_TABLE_END, 0x00},
|
||||
};
|
||||
|
||||
enum {
|
||||
AR0234_MODE_1920X1080_CROP_30FPS,
|
||||
AR0234_MODE_START_STREAM,
|
||||
AR0234_MODE_STOP_STREAM,
|
||||
AR0234_MODE_Dser_Ser,
|
||||
AR0234_MODE_Single_Dser_Ser,
|
||||
AR0234_MODE_TEST_PATTERN
|
||||
};
|
||||
|
||||
static struct index_reg_8 *mode_table[] = {
|
||||
[AR0234_MODE_1920X1080_CROP_30FPS]
|
||||
= ar0234_1920x1080_crop_30fps,
|
||||
[AR0234_MODE_START_STREAM]
|
||||
= ar0234_start,
|
||||
[AR0234_MODE_STOP_STREAM]
|
||||
= ar0234_stop,
|
||||
[AR0234_MODE_Dser_Ser] = ar0234_Double_Dser_Ser,
|
||||
[AR0234_MODE_Single_Dser_Ser] = ar0234_Single_Dser_Ser,
|
||||
[AR0234_MODE_TEST_PATTERN] = tp_colorbars,
|
||||
|
||||
};
|
||||
|
||||
static const int ar0234_30fps[] = {
|
||||
30,
|
||||
};
|
||||
|
||||
static const int ar0234_36fps[] = {
|
||||
36,
|
||||
};
|
||||
|
||||
static const int ar0234_18fps[] = {
|
||||
18,
|
||||
};
|
||||
static const int ar0234_60fps[] = {
|
||||
60,
|
||||
};
|
||||
|
||||
static const int ar0234_120fps[] = {
|
||||
120,
|
||||
};
|
||||
static const struct camera_common_frmfmt ar0234_frmfmt[] = {
|
||||
{{1920, 1200}, ar0234_60fps, 1, 0, AR0234_MODE_1920X1080_CROP_30FPS},
|
||||
};
|
||||
#endif /* __AR0234_I2C_TABLES__ */
|
||||
274
drivers/media/i2c/max96712.c
Normal file
274
drivers/media/i2c/max96712.c
Normal file
@@ -0,0 +1,274 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* max96712.c - max96712 IO Expander driver
|
||||
*
|
||||
* Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <media/camera_common.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
struct max96712 {
|
||||
struct i2c_client *i2c_client;
|
||||
struct regmap *regmap;
|
||||
const char *channel;
|
||||
};
|
||||
static struct max96712 *global_priv[4];
|
||||
|
||||
int max96712_write_reg_Dser(int slaveAddr, int channel, u16 addr, u8 val);
|
||||
int max96712_read_reg_Dser(int slaveAddr, int channel, u16 addr, unsigned int *val);
|
||||
|
||||
int max96712_write_reg_Dser(int slaveAddr, int channel,
|
||||
u16 addr, u8 val)
|
||||
{
|
||||
struct i2c_client *i2c_client = NULL;
|
||||
int bak = 0;
|
||||
int err;
|
||||
/* unsigned int ival = 0; */
|
||||
|
||||
if (channel > 3 || channel < 0 || global_priv[channel] == NULL)
|
||||
return -1;
|
||||
i2c_client = global_priv[channel]->i2c_client;
|
||||
bak = i2c_client->addr;
|
||||
|
||||
i2c_client->addr = slaveAddr / 2;
|
||||
err = regmap_write(global_priv[channel]->regmap, addr, val);
|
||||
|
||||
i2c_client->addr = bak;
|
||||
if (err) {
|
||||
dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n",
|
||||
__func__, addr, val);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(max96712_write_reg_Dser);
|
||||
|
||||
|
||||
int max96712_read_reg_Dser(int slaveAddr, int channel,
|
||||
u16 addr, unsigned int *val)
|
||||
{
|
||||
struct i2c_client *i2c_client = NULL;
|
||||
int bak = 0;
|
||||
int err;
|
||||
|
||||
if (channel > 3 || channel < 0 || global_priv[channel] == NULL)
|
||||
return -1;
|
||||
|
||||
i2c_client = global_priv[channel]->i2c_client;
|
||||
bak = i2c_client->addr;
|
||||
i2c_client->addr = slaveAddr / 2;
|
||||
|
||||
err = regmap_read(global_priv[channel]->regmap, addr, val);
|
||||
i2c_client->addr = bak;
|
||||
if (err) {
|
||||
dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n",
|
||||
__func__, addr, *val);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(max96712_read_reg_Dser);
|
||||
|
||||
static int max96712_read_reg(struct max96712 *priv,
|
||||
u16 addr, unsigned int *val)
|
||||
{
|
||||
struct i2c_client *i2c_client = priv->i2c_client;
|
||||
int err;
|
||||
|
||||
err = regmap_read(priv->regmap, addr, val);
|
||||
if (err)
|
||||
dev_err(&i2c_client->dev, "%s:i2c read failed, 0x%x = %x\n",
|
||||
__func__, addr, *val);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int max96712_stats_show(struct seq_file *s, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max96712_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, max96712_stats_show, inode->i_private);
|
||||
}
|
||||
|
||||
static ssize_t max96712_debugfs_write(struct file *s,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct max96712 *priv =
|
||||
((struct seq_file *)s->private_data)->private;
|
||||
struct i2c_client *i2c_client = priv->i2c_client;
|
||||
|
||||
char buf[255];
|
||||
int buf_size;
|
||||
int val = 0;
|
||||
|
||||
if (!user_buf || count <= 1)
|
||||
return -EFAULT;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf_size = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
return -EFAULT;
|
||||
|
||||
if (buf[0] == 'd') {
|
||||
dev_info(&i2c_client->dev, "%s, set daymode\n", __func__);
|
||||
max96712_read_reg(priv, 0x0010, &val);
|
||||
return count;
|
||||
}
|
||||
|
||||
if (buf[0] == 'n') {
|
||||
dev_info(&i2c_client->dev, "%s, set nightmode\n", __func__);
|
||||
return count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static const struct file_operations max96712_debugfs_fops = {
|
||||
.open = max96712_debugfs_open,
|
||||
.read = seq_read,
|
||||
.write = max96712_debugfs_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int max96712_debugfs_init(const char *dir_name,
|
||||
struct dentry **d_entry,
|
||||
struct dentry **f_entry,
|
||||
struct max96712 *priv)
|
||||
{
|
||||
struct dentry *dp, *fp;
|
||||
char dev_name[20];
|
||||
struct i2c_client *i2c_client = priv->i2c_client;
|
||||
struct device_node *np = i2c_client->dev.of_node;
|
||||
int err = 0;
|
||||
int index = 0;
|
||||
|
||||
if (np) {
|
||||
err = of_property_read_string(np, "channel", &priv->channel);
|
||||
if (err)
|
||||
dev_err(&i2c_client->dev, "channel not found\n");
|
||||
|
||||
err = snprintf(dev_name, sizeof(dev_name), "max96712_%s", priv->channel);
|
||||
if (err < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
index = priv->channel[0] - 'a';
|
||||
if (index < 0)
|
||||
return -EINVAL;
|
||||
global_priv[index] = priv;
|
||||
|
||||
dev_dbg(&i2c_client->dev, "%s: index %d\n", __func__, index);
|
||||
|
||||
dp = debugfs_create_dir(dev_name, NULL);
|
||||
if (dp == NULL) {
|
||||
dev_err(&i2c_client->dev, "%s: debugfs create dir failed\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fp = debugfs_create_file("max96712", 0644, dp, priv,
|
||||
&max96712_debugfs_fops);
|
||||
if (!fp) {
|
||||
dev_err(&i2c_client->dev, "%s: debugfs create file failed\n",
|
||||
__func__);
|
||||
debugfs_remove_recursive(dp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (d_entry)
|
||||
*d_entry = dp;
|
||||
if (f_entry)
|
||||
*f_entry = fp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct regmap_config max96712_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int max96712_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct max96712 *priv;
|
||||
int err = 0;
|
||||
|
||||
dev_info(&client->dev, "%s: enter\n", __func__);
|
||||
|
||||
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
|
||||
priv->i2c_client = client;
|
||||
priv->regmap = devm_regmap_init_i2c(priv->i2c_client,
|
||||
&max96712_regmap_config);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
dev_err(&client->dev,
|
||||
"regmap init failed: %ld\n", PTR_ERR(priv->regmap));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = max96712_debugfs_init(NULL, NULL, NULL, priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*set daymode by fault*/
|
||||
dev_info(&client->dev, "%s: success\n", __func__);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
|
||||
static int max96712_remove(struct i2c_client *client)
|
||||
#else
|
||||
static void max96712_remove(struct i2c_client *client)
|
||||
#endif
|
||||
{
|
||||
|
||||
if (client != NULL) {
|
||||
i2c_unregister_device(client);
|
||||
client = NULL;
|
||||
}
|
||||
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct i2c_device_id max96712_id[] = {
|
||||
{ "max96712", 0 },
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct of_device_id max96712_of_match[] = {
|
||||
{ .compatible = "nvidia,max96712", },
|
||||
{ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, max96712_id);
|
||||
|
||||
static struct i2c_driver max96712_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max96712",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = max96712_probe,
|
||||
.remove = max96712_remove,
|
||||
.id_table = max96712_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(max96712_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("IO Expander driver max96712");
|
||||
MODULE_AUTHOR("NVIDIA Corporation");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
1095
drivers/media/i2c/nv_ar0234.c
Normal file
1095
drivers/media/i2c/nv_ar0234.c
Normal file
File diff suppressed because it is too large
Load Diff
103
include/media/gmsl-link.h
Normal file
103
include/media/gmsl-link.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* <b>GMSL API: Gigabit Multimedia Serial Link protocol</b>
|
||||
*
|
||||
* @b Description: Defines elements used to set up and use a GMSL link.
|
||||
*/
|
||||
|
||||
#ifndef __GMSL_LINK_H__
|
||||
/**
|
||||
* \defgroup GMSL Gigabit Multimedia Serial Link (GMSL)
|
||||
*
|
||||
* Defines the interface used to control the MAX9295 serializer and
|
||||
* MAX9296 deserializer modules.
|
||||
*
|
||||
* @ingroup serdes_group
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define __GMSL_LINK_H__
|
||||
|
||||
#define GMSL_CSI_1X4_MODE 0x1
|
||||
#define GMSL_CSI_2X4_MODE 0x2
|
||||
#define GMSL_CSI_2X2_MODE 0x3
|
||||
#define GMSL_CSI_4X2_MODE 0x4
|
||||
|
||||
#define GMSL_CSI_PORT_A 0x0
|
||||
#define GMSL_CSI_PORT_B 0x1
|
||||
#define GMSL_CSI_PORT_C 0x2
|
||||
#define GMSL_CSI_PORT_D 0x3
|
||||
#define GMSL_CSI_PORT_E 0x4
|
||||
#define GMSL_CSI_PORT_F 0x5
|
||||
|
||||
#define GMSL_SERDES_CSI_LINK_A 0x1
|
||||
#define GMSL_SERDES_CSI_LINK_B 0x2
|
||||
|
||||
/* Didn't find kernel defintions, for now adding here */
|
||||
#define GMSL_CSI_DT_RAW_12 0x2C
|
||||
#define GMSL_CSI_DT_UED_U1 0x30
|
||||
#define GMSL_CSI_DT_EMBED 0x12
|
||||
|
||||
#define GMSL_ST_ID_UNUSED 0xFF
|
||||
|
||||
/**
|
||||
* Maximum number of data streams (\ref gmsl_stream elements) in a GMSL link
|
||||
* (\ref gmsl_link_ctx).
|
||||
*/
|
||||
#define GMSL_DEV_MAX_NUM_DATA_STREAMS 4
|
||||
|
||||
/**
|
||||
* Holds information about a data stream in a GMSL link (\ref gmsl_link_ctx).
|
||||
*/
|
||||
struct gmsl_stream {
|
||||
__u32 st_id_sel;
|
||||
__u32 st_data_type;
|
||||
__u32 des_pipe;
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds the configuration of the GMSL links from a sensor to its serializer to
|
||||
* its deserializer.
|
||||
*/
|
||||
struct gmsl_link_ctx {
|
||||
/**< Default sensor virtual channel. */
|
||||
__u32 st_vc;
|
||||
/**< Destination virtual channel (user-defined). */
|
||||
__u32 dst_vc;
|
||||
/**< Sensor to serializer CSI port connection. */
|
||||
__u32 src_csi_port;
|
||||
/**< Deserializer to Jetson CSI port connection. */
|
||||
__u32 dst_csi_port;
|
||||
/**< GMSL link between serializer and deserializer devices. */
|
||||
__u32 serdes_csi_link;
|
||||
/**< Number of active streams to be mapped from sensor. */
|
||||
__u32 num_streams;
|
||||
/**< Sensor's CSI lane configuration. */
|
||||
__u32 num_csi_lanes;
|
||||
/**< Deserializer CSI mode. */
|
||||
__u32 csi_mode;
|
||||
/**< Serializer slave address. */
|
||||
__u32 ser_reg;
|
||||
/**< Sensor proxy slave address. */
|
||||
__u32 sdev_reg;
|
||||
/**< Sensor default slave address. */
|
||||
__u32 sdev_def;
|
||||
/**< Indicates whether the serializer device for
|
||||
* the specified sensor source was found. Set by
|
||||
* the serializer driver during setup; used by
|
||||
* the deserializer driver to choose certain
|
||||
* configuration settings during setup.
|
||||
*/
|
||||
bool serdev_found;
|
||||
/*< An array of information about the data streams in the link. */
|
||||
struct gmsl_stream streams[GMSL_DEV_MAX_NUM_DATA_STREAMS];
|
||||
/**< Sensor device handle. */
|
||||
struct device *s_dev;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __GMSL_LINK_H__ */
|
||||
87
include/media/max9295.h
Normal file
87
include/media/max9295.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* <b>MAX9295 API: For Maxim Integrated MAX9295 serializer</b>
|
||||
*
|
||||
* @b Description: Defines elements used to set up and use a
|
||||
* Maxim Integrated MAX9295 serializer.
|
||||
*/
|
||||
|
||||
#ifndef __MAX9295_H__
|
||||
#define __MAX9295_H__
|
||||
|
||||
#include <media/gmsl-link.h>
|
||||
/**
|
||||
* \defgroup max9295 MAX9295 serializer driver
|
||||
*
|
||||
* Controls the MAX9295 serializer module.
|
||||
*
|
||||
* @ingroup serdes_group
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Powers on a serializer device and performs the I2C overrides
|
||||
* for sensor and serializer devices.
|
||||
*
|
||||
* The I2C overrides include setting proxy I2C slave addresses for the devices.
|
||||
*
|
||||
* Before the client calls this function it must ensure that
|
||||
* the deserializer device is in link_ex exclusive link mode
|
||||
* by calling the deserializer driver's max9296_setup_link() function.
|
||||
*
|
||||
* @param [in] dev The serializer device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9295_setup_control(struct device *dev);
|
||||
|
||||
/**
|
||||
* Reverts I2C overrides and resets a serializer device.
|
||||
*
|
||||
* @param [in] dev The serializer device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9295_reset_control(struct device *dev);
|
||||
|
||||
/**
|
||||
* @brief Pairs a sensor device with a serializer device.
|
||||
*
|
||||
* To be called by sensor client driver.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] g_ctx The @ref gmsl_link_ctx structure handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9295_sdev_pair(struct device *dev, struct gmsl_link_ctx *g_ctx);
|
||||
|
||||
/**
|
||||
* @brief Unpairs a sensor device from a serializer device.
|
||||
*
|
||||
* To be called by sensor client driver.
|
||||
*
|
||||
* @param [in] dev The serializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9295_sdev_unpair(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* Sets up the serializer device's internal pipeline for a specified
|
||||
* sensor/serializer pair.
|
||||
*
|
||||
* @param [in] dev The serializer device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9295_setup_streaming(struct device *dev);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __MAX9295_H__ */
|
||||
151
include/media/max9296.h
Normal file
151
include/media/max9296.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* <b>MAX9296 API: For Maxim Integrated MAX9296 deserializer</b>
|
||||
*
|
||||
* @b Description: Defines elements used to set up and use a
|
||||
* Maxim Integrated MAX9296 deserializer.
|
||||
*/
|
||||
|
||||
#ifndef __MAX9296_H__
|
||||
#define __MAX9296_H__
|
||||
|
||||
#include <media/gmsl-link.h>
|
||||
/**
|
||||
* \defgroup max9296 MAX9296 deserializer driver
|
||||
*
|
||||
* Controls the MAX9296 deserializer module.
|
||||
*
|
||||
* @ingroup serdes_group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Puts a deserializer device in single exclusive link mode, so link-specific
|
||||
* I2C overrides can be performed for sensor and serializer devices.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_setup_link(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Sets up a deserializer link's control pipeline.
|
||||
*
|
||||
* Puts the deserializer in dual splitter mode. You must call this function
|
||||
* during device boot, after max9296_setup_link().
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_setup_control(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Resets a deserializer device's link control pipeline.
|
||||
*
|
||||
* The deserializer driver internally decrements the reference count and
|
||||
* resets the deserializer device if all the source sensor devices are
|
||||
* powered off, resetting all control and streaming configuration.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_reset_control(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Registers a source sensor device with a deserializer device.
|
||||
*
|
||||
* The deserializer driver internally checks all perquisites and compatibility
|
||||
* factors. If it finds that the registration request is valid,
|
||||
* it stores the source's @ref gmsl_link_ctx context handle in the source list
|
||||
* maintained by the deserializer driver instance.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] g_ctx A @c gmsl_link_ctx structure handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx);
|
||||
|
||||
/**
|
||||
* Unregisters a source sensor device from its deserializer device.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_sdev_unregister(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* Performs internal pipeline configuration for a link in context to set up
|
||||
* streaming, and puts the deserializer link in ready-to-stream state.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 or success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_setup_streaming(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Enables streaming.
|
||||
*
|
||||
* This function is to be called by the sensor client driver.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_start_streaming(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Disables streaming.
|
||||
*
|
||||
* This function is to be called by the sensor client driver.
|
||||
*
|
||||
* @note Both @c max9296_start_streaming and @c max9296_stop_streaming
|
||||
* are mainly added to enable and disable sensor streaming on the fly
|
||||
* while other sensors are active.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
* @param [in] s_dev The sensor device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_stop_streaming(struct device *dev, struct device *s_dev);
|
||||
|
||||
/**
|
||||
* @brief Powers on the max9296 deserializer module.
|
||||
*
|
||||
* Asserts shared reset GPIO and powers on the regulator;
|
||||
* maintains the reference count internally for source devices.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
*
|
||||
* @return 0 for success, or -1 otherwise.
|
||||
*/
|
||||
int max9296_power_on(struct device *dev);
|
||||
|
||||
/**
|
||||
* @brief Powers off the max9296 deserializer module.
|
||||
*
|
||||
* Deasserts the shared reset GPIO and powers off the regulator based on
|
||||
* the reference count.
|
||||
*
|
||||
* @param [in] dev The deserializer device handle.
|
||||
*/
|
||||
void max9296_power_off(struct device *dev);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __MAX9296_H__ */
|
||||
Reference in New Issue
Block a user