Compare commits
110
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
502a0ff21a | ||
|
|
9359ba377c | ||
|
|
63f7efc319 | ||
|
|
08bd2cf2fd | ||
|
|
3e090e8a5a | ||
|
|
2aa5b04a01 | ||
|
|
5c7245e156 | ||
|
|
823de1bf0a | ||
|
|
9261922c66 | ||
|
|
6c42b74e14 | ||
|
|
cd75bcb1f9 | ||
|
|
36fa0b8913 | ||
|
|
dcea3dc03a | ||
|
|
dd36ee6907 | ||
|
|
cdd38f1012 | ||
|
|
f70d95850e | ||
|
|
4f8d7f167d | ||
|
|
965c9d231b | ||
|
|
2fcfbdae10 | ||
|
|
d3fd5a30ad | ||
|
|
91275a8004 | ||
|
|
670265a2ca | ||
|
|
05fe91af04 | ||
|
|
d0828055d5 | ||
|
|
3690f129b6 | ||
|
|
a21e956221 | ||
|
|
47101f1600 | ||
|
|
79d808ff03 | ||
|
|
e6ea914769 | ||
|
|
a5aef46a18 | ||
|
|
b54d304a10 | ||
|
|
e04cc94e55 | ||
|
|
407b8ee51b | ||
|
|
972c60c721 | ||
|
|
77412a8302 | ||
|
|
bafa332c10 | ||
|
|
9642e53c2c | ||
|
|
c01ca7c586 | ||
|
|
55d991543c | ||
|
|
d5c4098152 | ||
|
|
35e22c8e05 | ||
|
|
e2e53ae79a | ||
|
|
e4c7dc6b80 | ||
|
|
adc3327467 | ||
|
|
b7b1575ade | ||
|
|
2fa462786f | ||
|
|
c1199061b4 | ||
|
|
7390834040 | ||
|
|
f3c7a9908f | ||
|
|
db5460d78a | ||
|
|
90b5a2e220 | ||
|
|
5451612c9c | ||
|
|
f15bdd8f1f | ||
|
|
a434425e73 | ||
|
|
66a1caddd5 | ||
|
|
037b91b974 | ||
|
|
6a2d2c6887 | ||
|
|
4c4e537de4 | ||
|
|
18abb022ab | ||
|
|
61eb99267d | ||
|
|
64754792ed | ||
|
|
fac12575c4 | ||
|
|
587dd0e9fc | ||
|
|
37c5760c35 | ||
|
|
15edaf962d | ||
|
|
415f474a30 | ||
|
|
f5817e0969 | ||
|
|
e8cabae6ec | ||
|
|
d936e3daaf | ||
|
|
f14a1b1af6 | ||
|
|
05e87bf9ef | ||
|
|
2cdbb848ac | ||
|
|
7b74031652 | ||
|
|
a0b78d8bb6 | ||
|
|
41c7e5b923 | ||
|
|
3414bc92e8 | ||
|
|
d39948ba5f | ||
|
|
1af6832aa1 | ||
|
|
9f99fb469d | ||
|
|
9652725d15 | ||
|
|
b1f8d8dc78 | ||
|
|
e7c5dae9a0 | ||
|
|
093f3edc50 | ||
|
|
c97121ef23 | ||
|
|
86b5a9c905 | ||
|
|
2cab2ab41f | ||
|
|
40474da663 | ||
|
|
0490038044 | ||
|
|
f8401a72d8 | ||
|
|
fa3635b142 | ||
|
|
7fc6394176 | ||
|
|
156132864e | ||
|
|
523114b93c | ||
|
|
0fd3f43820 | ||
|
|
d56c180dba | ||
|
|
1789b75e32 | ||
|
|
1df0cc2a82 | ||
|
|
34e509d5e5 | ||
|
|
3d913d9051 | ||
|
|
f06e70573e | ||
|
|
62729c112f | ||
|
|
9bbaf832bb | ||
|
|
c7465408be | ||
|
|
08c08b7b32 | ||
|
|
9e79aefb8f | ||
|
|
10fc7db687 | ||
|
|
935ca443cb | ||
|
|
5c743de761 | ||
|
|
0df5550822 | ||
|
|
a797a11437 |
No files matched your search
@@ -506,7 +506,6 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
|
||||
{ 0x6606, "BCM4345C5" }, /* 003.006.006 */
|
||||
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */
|
||||
{ 0x2310, "BCM4343A2" }, /* 001.003.016 */
|
||||
{ 0x2409, "BCM4356A3" }, /* 001.004.009 */
|
||||
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
|
||||
{ 0x420d, "BCM4349B1" }, /* 002.002.013 */
|
||||
{ 0x420e, "BCM4349B1" }, /* 002.002.014 */
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/sched/clock.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#include <soc/tegra/bpmp.h>
|
||||
#include <soc/tegra/bpmp-abi.h>
|
||||
@@ -344,12 +343,28 @@ static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
|
||||
|
||||
static int __maybe_unused tegra_bpmp_resume(struct device *dev);
|
||||
|
||||
static int __tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
|
||||
struct tegra_bpmp_message *msg)
|
||||
int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
|
||||
struct tegra_bpmp_message *msg)
|
||||
{
|
||||
struct tegra_bpmp_channel *channel = bpmp->tx_channel;
|
||||
struct tegra_bpmp_channel *channel;
|
||||
int err;
|
||||
|
||||
if (WARN_ON(!irqs_disabled()))
|
||||
return -EPERM;
|
||||
|
||||
if (!tegra_bpmp_message_valid(msg))
|
||||
return -EINVAL;
|
||||
|
||||
if (bpmp->suspended) {
|
||||
/* Reset BPMP IPC channels during resume based on flags passed */
|
||||
if (msg->flags & TEGRA_BPMP_MESSAGE_RESET)
|
||||
tegra_bpmp_resume(bpmp->dev);
|
||||
else
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
channel = bpmp->tx_channel;
|
||||
|
||||
spin_lock(&bpmp->atomic_tx_lock);
|
||||
|
||||
err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK,
|
||||
@@ -372,26 +387,6 @@ static int __tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
|
||||
return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size,
|
||||
&msg->rx.ret);
|
||||
}
|
||||
|
||||
int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
|
||||
struct tegra_bpmp_message *msg)
|
||||
{
|
||||
if (WARN_ON(!irqs_disabled()))
|
||||
return -EPERM;
|
||||
|
||||
if (!tegra_bpmp_message_valid(msg))
|
||||
return -EINVAL;
|
||||
|
||||
if (bpmp->suspended) {
|
||||
/* Reset BPMP IPC channels during resume based on flags passed */
|
||||
if (msg->flags & TEGRA_BPMP_MESSAGE_RESET)
|
||||
tegra_bpmp_resume(bpmp->dev);
|
||||
else
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return __tegra_bpmp_transfer_atomic(bpmp, msg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_bpmp_transfer_atomic);
|
||||
|
||||
int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
|
||||
@@ -738,37 +733,6 @@ void tegra_bpmp_handle_rx(struct tegra_bpmp *bpmp)
|
||||
spin_unlock(&bpmp->lock);
|
||||
}
|
||||
|
||||
#define MRQ_T210_ENABLE_SUSPEND 17
|
||||
#define TEGRA210_BPMP_PM_SC7 23
|
||||
|
||||
static int tegra210_bpmp_syscore_suspend(void *data)
|
||||
{
|
||||
struct tegra_bpmp *bpmp = data;
|
||||
__le32 req[2] = { cpu_to_le32(TEGRA210_BPMP_PM_SC7), 0 };
|
||||
struct tegra_bpmp_message msg = {
|
||||
.mrq = MRQ_T210_ENABLE_SUSPEND,
|
||||
.tx = {
|
||||
.data = req,
|
||||
.size = sizeof(req),
|
||||
},
|
||||
};
|
||||
int err;
|
||||
|
||||
err = __tegra_bpmp_transfer_atomic(bpmp, &msg);
|
||||
if (err < 0)
|
||||
dev_err(bpmp->dev, "failed to enable SC7: %d\n", err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct syscore_ops tegra210_bpmp_syscore_ops = {
|
||||
.suspend = tegra210_bpmp_syscore_suspend,
|
||||
};
|
||||
|
||||
static struct syscore tegra210_bpmp_syscore = {
|
||||
.ops = &tegra210_bpmp_syscore_ops,
|
||||
};
|
||||
|
||||
static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_bpmp *bpmp;
|
||||
@@ -867,11 +831,6 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
if (err < 0)
|
||||
dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err);
|
||||
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "nvidia,tegra210-bpmp")) {
|
||||
tegra210_bpmp_syscore.data = bpmp;
|
||||
register_syscore(&tegra210_bpmp_syscore);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_mrq:
|
||||
|
||||
@@ -53,10 +53,6 @@
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL ((u8)BIT(3))
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL ((u8)BIT(5))
|
||||
|
||||
#define DCS_SM_BRIGHTNESS_MAX 2047
|
||||
#define DCS_SM_DUTY_MAX 255
|
||||
#define DCS_SM_DUTY_DEFAULT 150
|
||||
|
||||
/* OLED Panels color mode */
|
||||
#define DCS_SM_COLOR_MODE_SATURATED ((u8)0x00) /* Disabled. Similar to vivid but over-saturated. Wide gamut? */
|
||||
#define DCS_SM_COLOR_MODE_WASHED ((u8)0x45)
|
||||
@@ -114,7 +110,6 @@ struct nx_panel {
|
||||
|
||||
bool prepared;
|
||||
bool enabled;
|
||||
bool dcs_backlight;
|
||||
|
||||
const struct drm_display_mode *mode;
|
||||
enum drm_panel_orientation orientation;
|
||||
@@ -136,7 +131,6 @@ struct init_cmd init_cmds_default[] = {
|
||||
0xFF,
|
||||
20,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd init_cmds_PANEL_JDI_XXX062M[] = {
|
||||
@@ -199,41 +193,35 @@ struct init_cmd suspend_cmds_PANEL_JDI_XXX062M[] = {
|
||||
};
|
||||
|
||||
struct init_cmd init_cmds_PANEL_SAM_AMS699VC01[] = {
|
||||
{ MIPI_DCS_EXIT_SLEEP_MODE, 0, { 0x00 } },
|
||||
{ MIPI_DCS_EXIT_SLEEP_MODE, 2, { 0x00, 0x0 } },
|
||||
{
|
||||
0xFF,
|
||||
180,
|
||||
},
|
||||
|
||||
// Set color mode to basic (natural). Stock is Saturated (0x00). (Reset value is 0x20).
|
||||
{ MIPI_DCS_PRIV_SM_SET_COLOR_MODE, 1, { DCS_SM_COLOR_MODE_BASIC } },
|
||||
{ MIPI_DCS_PRIV_SM_SET_COLOR_MODE, 2, { 0x23, 0x0 } },
|
||||
|
||||
// Enable backlight and smooth PWM.
|
||||
{ MIPI_DCS_WRITE_CONTROL_DISPLAY, 1, { DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL } },
|
||||
{ MIPI_DCS_WRITE_CONTROL_DISPLAY, 2, { 0x28, 0x0 } },
|
||||
|
||||
// Unlock Level 2 registers.
|
||||
{ MIPI_DCS_PRIV_SM_SET_REGS_LOCK, 4, { 0x5A, 0x5A, 0x5A, 0x5A } },
|
||||
{ 0x05, 9, { 0x0, 0x0, 0xE2, 0x5A, 0x5A, 0x5A, 0x5A, 0x0, 0x0 } },
|
||||
|
||||
// Set registers offset and set PWM transition to 6 frames (100ms).
|
||||
{ MIPI_DCS_PRIV_SM_SET_REG_OFFSET, 1, { 0x07 } },
|
||||
{ MIPI_DCS_PRIV_SM_SET_ELVSS, 1, { 0x06 } },
|
||||
{ MIPI_DCS_PRIV_SM_SET_REG_OFFSET, 2, { 0x07, 0x0 } },
|
||||
{ MIPI_DCS_PRIV_SM_SET_ELVSS, 2, { 0x06, 0x0 } },
|
||||
|
||||
// Relock Level 2 registers.
|
||||
{ MIPI_DCS_PRIV_SM_SET_REGS_LOCK, 4, { 0x5A, 0x5A, 0xA5, 0xA5 } },
|
||||
{ 0x05, 9, { 0x0, 0x0, 0xE2, 0x5A, 0x5A, 0xA5, 0xA5, 0x0, 0x0 } },
|
||||
|
||||
// MIPI_DCS_SET_BRIGHTNESS 0000: 0%. 07FF: 100%.
|
||||
{ MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 2, { 0x00, 0x00 } },
|
||||
// MIPI_DCS_SET_BRIGHTNESS 0000: 0%. FF07: 100%.
|
||||
{ 0x03, 7, { 0x00, 0x00, 0x51, 0x0, 0x0, 0x0, 0x0 } },
|
||||
|
||||
{
|
||||
0xFF,
|
||||
5,
|
||||
},
|
||||
{ MIPI_DCS_SET_DISPLAY_ON, 0, { 0x00 } },
|
||||
{
|
||||
0xFF,
|
||||
20,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd init_cmds_PANEL_AUO_A062TAN01[] = {
|
||||
@@ -248,7 +236,6 @@ struct init_cmd init_cmds_PANEL_AUO_A062TAN01[] = {
|
||||
5,
|
||||
},
|
||||
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 6, { 0x48, 0x11, 0x71, 0x09, 0x32, 0x14 } },
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd suspend_cmds_PANEL_AUO_A062TAN01[] = {
|
||||
@@ -265,7 +252,6 @@ struct init_cmd suspend_cmds_PANEL_AUO_A062TAN01[] = {
|
||||
0xFF,
|
||||
50,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd suspend_cmds_PANEL_AUO_A055TAN01[] = {
|
||||
@@ -288,7 +274,6 @@ struct init_cmd suspend_cmds_PANEL_AUO_A055TAN01[] = {
|
||||
0xFF,
|
||||
50,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd init_cmds_PANEL_INL_P062CCA_AZ1[] = {
|
||||
@@ -304,7 +289,6 @@ struct init_cmd init_cmds_PANEL_INL_P062CCA_AZ1[] = {
|
||||
},
|
||||
{ MIPI_DCS_PRIV_SET_POWER_CONTROL, 6, { 0x48, 0x15, 0x75, 0x09, 0x32, 0x14 } },
|
||||
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd suspend_cmds_PANEL_INL_2J055IA_27A[] = {
|
||||
@@ -327,7 +311,6 @@ struct init_cmd suspend_cmds_PANEL_INL_2J055IA_27A[] = {
|
||||
0xFF,
|
||||
50,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd suspend_cmds_PANEL_SHP_LQ055T1SW10[] = {
|
||||
@@ -350,21 +333,18 @@ struct init_cmd suspend_cmds_PANEL_SHP_LQ055T1SW10[] = {
|
||||
0xFF,
|
||||
50,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
struct init_cmd suspend_cmds_PANEL_SAM_AMS699VC01[] = {
|
||||
{ MIPI_DCS_SET_DISPLAY_OFF, 0, { 0x00 } },
|
||||
{
|
||||
0xFF,
|
||||
100,
|
||||
},
|
||||
{ MIPI_DCS_ENTER_SLEEP_MODE, 0, { 0x00 } },
|
||||
{ MIPI_DCS_ENTER_SLEEP_MODE, 2, { 0x00, 0x0 } },
|
||||
{
|
||||
0xFF,
|
||||
120,
|
||||
},
|
||||
{ MIPI_DCS_NOP, -1, { 0x00 } },
|
||||
};
|
||||
|
||||
static inline struct nx_panel *to_nx_panel(struct drm_panel *panel)
|
||||
@@ -372,43 +352,23 @@ static inline struct nx_panel *to_nx_panel(struct drm_panel *panel)
|
||||
return container_of(panel, struct nx_panel, base);
|
||||
}
|
||||
|
||||
static u16 nx_dcs_brightness(struct backlight_device *bl)
|
||||
{
|
||||
if (backlight_is_blank(bl))
|
||||
return 0;
|
||||
|
||||
if (bl->props.brightness >= DCS_SM_DUTY_MAX)
|
||||
return DCS_SM_BRIGHTNESS_MAX;
|
||||
|
||||
return max(bl->props.brightness, 1) *
|
||||
(DCS_SM_BRIGHTNESS_MAX / DCS_SM_DUTY_MAX);
|
||||
}
|
||||
|
||||
static void nx_panel_detect(struct nx_panel *nx)
|
||||
{
|
||||
u8 id[3] = { 0 };
|
||||
int ret;
|
||||
nx->init_cmds = NULL;
|
||||
nx->suspend_cmds = NULL;
|
||||
|
||||
nx->display_id = 0;
|
||||
memset(&(nx->display_id), 0, sizeof(nx->display_id));
|
||||
|
||||
ret = mipi_dsi_dcs_read(nx->dsi, MIPI_DCS_GET_DISPLAY_ID,
|
||||
id, sizeof(id));
|
||||
&(nx->display_id), sizeof(nx->display_id));
|
||||
if (ret < 0) {
|
||||
dev_err(&nx->dsi->dev, "failed to read panel ID: %d\n", ret);
|
||||
} else {
|
||||
nx->display_id = (id[2] << 8) | id[0];
|
||||
dev_info_once(&nx->dsi->dev, "display ID[%d]: %02x %02x %02x\n",
|
||||
ret, id[0], id[1], id[2]);
|
||||
dev_info(&nx->dsi->dev, "display ID[%d]: %04x\n",
|
||||
ret, nx->display_id);
|
||||
}
|
||||
|
||||
if ((nx->display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
nx->display_id = PANEL_JDI_XXX062M;
|
||||
|
||||
if (of_machine_is_compatible("nintendo,aula"))
|
||||
nx->display_id = PANEL_SAM_AMS699VC01;
|
||||
|
||||
dev_info(&nx->dsi->dev,
|
||||
"setting init sequence for ID %04x\n", nx->display_id);
|
||||
|
||||
@@ -533,21 +493,6 @@ static int nx_panel_init(struct nx_panel *nx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (nx->dcs_backlight) {
|
||||
u8 mode;
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_brightness_large(dsi,
|
||||
nx_dcs_brightness(nx->backlight));
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to set brightness: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_get_power_mode(dsi, &mode);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "failed to read power mode: %d\n", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -574,9 +519,6 @@ static int nx_panel_disable(struct drm_panel *panel)
|
||||
|
||||
backlight_disable(nx->backlight);
|
||||
|
||||
if (nx->dcs_backlight)
|
||||
mipi_dsi_dcs_set_display_off(nx->dsi);
|
||||
|
||||
nx->enabled = false;
|
||||
|
||||
return 0;
|
||||
@@ -665,7 +607,7 @@ static const struct drm_display_mode default_mode = {
|
||||
.htotal = 720 + 136 + 72 + 72,
|
||||
.vdisplay = 1280,
|
||||
.vsync_start = 1280 + 10,
|
||||
.vsync_end = 1280 + 10 + 1,
|
||||
.vsync_end = 1280 + 10 + 2,
|
||||
.vtotal = 1280 + 10 + 1 + 9,
|
||||
.flags = 0,
|
||||
};
|
||||
@@ -692,6 +634,8 @@ static int nx_panel_get_modes(struct drm_panel *panel,
|
||||
connector->display_info.height_mm = 137;
|
||||
connector->display_info.bpc = 8;
|
||||
|
||||
drm_connector_set_panel_orientation(connector, nx->orientation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -711,21 +655,6 @@ static const struct drm_panel_funcs nx_panel_funcs = {
|
||||
.get_orientation = nx_panel_get_orientation,
|
||||
};
|
||||
|
||||
static int nx_dcs_backlight_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct nx_panel *nx = bl_get_data(bl);
|
||||
|
||||
if (!nx->prepared)
|
||||
return 0;
|
||||
|
||||
return mipi_dsi_dcs_set_display_brightness_large(nx->dsi,
|
||||
nx_dcs_brightness(bl));
|
||||
}
|
||||
|
||||
static const struct backlight_ops nx_dcs_backlight_ops = {
|
||||
.update_status = nx_dcs_backlight_update_status,
|
||||
};
|
||||
|
||||
static int nx_panel_add(struct nx_panel *nx)
|
||||
{
|
||||
struct device *dev = &nx->dsi->dev;
|
||||
@@ -760,20 +689,6 @@ static int nx_panel_add(struct nx_panel *nx)
|
||||
|
||||
if (!nx->backlight)
|
||||
return -EPROBE_DEFER;
|
||||
} else {
|
||||
struct backlight_properties props = {
|
||||
.type = BACKLIGHT_RAW,
|
||||
.brightness = DCS_SM_DUTY_DEFAULT,
|
||||
.max_brightness = DCS_SM_DUTY_MAX,
|
||||
};
|
||||
|
||||
nx->backlight = devm_backlight_device_register(dev, "backlight", dev, nx,
|
||||
&nx_dcs_backlight_ops,
|
||||
&props);
|
||||
if (IS_ERR(nx->backlight))
|
||||
return PTR_ERR(nx->backlight);
|
||||
|
||||
nx->dcs_backlight = true;
|
||||
}
|
||||
|
||||
ret = of_drm_get_panel_orientation(dev->of_node, &nx->orientation);
|
||||
@@ -795,7 +710,7 @@ static void nx_panel_del(struct nx_panel *nx)
|
||||
if (nx->base.dev)
|
||||
drm_panel_remove(&nx->base);
|
||||
|
||||
if (nx->backlight && !nx->dcs_backlight)
|
||||
if (nx->backlight)
|
||||
put_device(&nx->backlight->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <drm/drm_panel.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_simple_kms_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "dc.h"
|
||||
#include "drm.h"
|
||||
@@ -1075,9 +1074,6 @@ static int tegra_dsi_init(struct host1x_client *client)
|
||||
&tegra_dsi_connector_helper_funcs);
|
||||
dsi->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
||||
|
||||
drm_connector_set_orientation_from_panel(
|
||||
&dsi->output.connector, dsi->output.panel);
|
||||
|
||||
drm_simple_encoder_init(drm, &dsi->output.encoder,
|
||||
DRM_MODE_ENCODER_DSI);
|
||||
drm_encoder_helper_add(&dsi->output.encoder,
|
||||
@@ -1346,39 +1342,6 @@ static void tegra_dsi_writesl(struct tegra_dsi *dsi, unsigned long offset,
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t tegra_dsi_video_transfer(struct tegra_dsi *dsi,
|
||||
const struct mipi_dsi_packet *packet)
|
||||
{
|
||||
const u8 *header = packet->header;
|
||||
u32 host_control, value;
|
||||
|
||||
host_control = tegra_dsi_readl(dsi, DSI_HOST_CONTROL);
|
||||
|
||||
value = DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_TX_TRIG_SOL |
|
||||
DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
|
||||
tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
|
||||
|
||||
value = DSI_VIDEO_MODE_CMD_PKT_ENABLE | DSI_VIDEO_MODE_LINE_TYPE(4);
|
||||
tegra_dsi_writel(dsi, value, DSI_VIDEO_MODE_CONTROL);
|
||||
|
||||
value = header[2] << 16 | header[1] << 8 | header[0];
|
||||
tegra_dsi_writel(dsi, value, DSI_WR_DATA);
|
||||
|
||||
if (packet->payload_length > 0)
|
||||
tegra_dsi_writesl(dsi, DSI_WR_DATA, packet->payload,
|
||||
packet->payload_length);
|
||||
|
||||
if (dsi->output.encoder.crtc) {
|
||||
drm_crtc_wait_one_vblank(dsi->output.encoder.crtc);
|
||||
drm_crtc_wait_one_vblank(dsi->output.encoder.crtc);
|
||||
}
|
||||
|
||||
tegra_dsi_writel(dsi, 0, DSI_VIDEO_MODE_CONTROL);
|
||||
tegra_dsi_writel(dsi, host_control, DSI_HOST_CONTROL);
|
||||
|
||||
return packet->size;
|
||||
}
|
||||
|
||||
static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
const struct mipi_dsi_msg *msg)
|
||||
{
|
||||
@@ -1399,16 +1362,14 @@ static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
if (packet.size > dsi->video_fifo_depth * 4)
|
||||
return -ENOSPC;
|
||||
|
||||
if (tegra_dsi_readl(dsi, DSI_CONTROL) & DSI_CONTROL_VIDEO_ENABLE) {
|
||||
if (msg->rx_buf && msg->rx_len > 0)
|
||||
return -EBUSY;
|
||||
|
||||
return tegra_dsi_video_transfer(dsi, &packet);
|
||||
/* reset underflow/overflow flags */
|
||||
value = tegra_dsi_readl(dsi, DSI_STATUS);
|
||||
if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) {
|
||||
value = DSI_HOST_CONTROL_FIFO_RESET;
|
||||
tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
|
||||
usleep_range(10, 20);
|
||||
}
|
||||
|
||||
tegra_dsi_writel(dsi, DSI_HOST_CONTROL_FIFO_RESET, DSI_HOST_CONTROL);
|
||||
usleep_range(10, 20);
|
||||
|
||||
value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
|
||||
value |= DSI_POWER_CONTROL_ENABLE;
|
||||
tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
|
||||
|
||||
@@ -102,8 +102,6 @@
|
||||
#define DSI_PAD_CONTROL_CD 0x4c
|
||||
#define DSI_PAD_CD_STATUS 0x4d
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4e
|
||||
#define DSI_VIDEO_MODE_CMD_PKT_ENABLE (1 << 0)
|
||||
#define DSI_VIDEO_MODE_LINE_TYPE(x) (((x) & 0x7) << 1)
|
||||
#define DSI_PAD_CONTROL_1 0x4f
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
#define DSI_PAD_OUT_CLK(x) (((x) & 0x7) << 0)
|
||||
|
||||
@@ -135,16 +135,6 @@ config AS73211
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called as73211.
|
||||
|
||||
config BH1730
|
||||
tristate "ROHM BH1730 ambient light sensor"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here to build support for the ROHM BH1730FVC ambient light
|
||||
sensor.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called bh1730.
|
||||
|
||||
config BH1745
|
||||
tristate "ROHM BH1745 colour sensor"
|
||||
depends on I2C
|
||||
|
||||
@@ -15,7 +15,6 @@ obj-$(CONFIG_APDS9300) += apds9300.o
|
||||
obj-$(CONFIG_APDS9306) += apds9306.o
|
||||
obj-$(CONFIG_APDS9960) += apds9960.o
|
||||
obj-$(CONFIG_AS73211) += as73211.o
|
||||
obj-$(CONFIG_BH1730) += bh1730.o
|
||||
obj-$(CONFIG_BH1745) += bh1745.o
|
||||
obj-$(CONFIG_BH1750) += bh1750.o
|
||||
obj-$(CONFIG_BH1780) += bh1780.o
|
||||
|
||||
@@ -1,575 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ROHM BH1730 ambient light sensor driver
|
||||
*
|
||||
* Copyright (c) 2021 CTCaer <ctcaer@gmail.com>
|
||||
*
|
||||
* Based on previous iio BH1730FVC drivers from:
|
||||
* Copyright (c) 2018 Google, Inc.
|
||||
* Author: Pierre Bourdon <delroth@google.com>
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
|
||||
* Author: Won Huh <won.huh@samsung.com>
|
||||
*
|
||||
* Data sheets:
|
||||
* http://www.rohm.com/web/global/datasheet/BH1730FVC/bh1730fvc-e
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#define BH1730_NAME "bh1730fvc"
|
||||
|
||||
#define BH1730_CMD_BIT BIT(7)
|
||||
|
||||
#define BH1730_REG_CONTROL 0x00
|
||||
#define BH1730_REG_TIMING 0x01
|
||||
#define BH1730_REG_GAIN 0x07
|
||||
#define BH1730_REG_DATA0LOW 0x14
|
||||
#define BH1730_REG_DATA1LOW 0x16
|
||||
|
||||
#define BH1730_CONTROL_POWER BIT(0)
|
||||
#define BH1730_CONTROL_ADC_EN BIT(1)
|
||||
|
||||
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
|
||||
#define BH1730_ITIME_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
|
||||
|
||||
#define BH1730_DEFAULT_INTEG_CYCLE 38
|
||||
#define BH1730_DEFAULT_ITIME_MS 100
|
||||
|
||||
#define BH1730_POWER_ON_DELAY_US 10000
|
||||
|
||||
#define BH1730_MAX_MEASURED_LUX 100000
|
||||
|
||||
enum bh1730_gain {
|
||||
BH1730_GAIN_1X = 0,
|
||||
BH1730_GAIN_2X,
|
||||
BH1730_GAIN_64X,
|
||||
BH1730_GAIN_128X,
|
||||
};
|
||||
|
||||
struct gain_coeff_t {
|
||||
u32 cl;
|
||||
u32 fl;
|
||||
};
|
||||
|
||||
struct opt_win_coeff_t {
|
||||
u32 rc;
|
||||
u32 cv;
|
||||
u32 ci;
|
||||
};
|
||||
|
||||
struct lux_cal_data_t {
|
||||
const struct gain_coeff_t *gain_coeff;
|
||||
const struct opt_win_coeff_t *opt_win_coeff;
|
||||
u32 opt_win_coeff_count;
|
||||
u32 itime_cycle;
|
||||
u32 mul;
|
||||
};
|
||||
|
||||
/*
|
||||
* No optical window or optical window that has flat transmittance
|
||||
* from visible light to infrared light.
|
||||
*/
|
||||
static const struct opt_win_coeff_t def_lux_coeff[] = {
|
||||
{ 260, 1290, 2733 },
|
||||
{ 550, 795, 859 },
|
||||
{ 1090, 510, 345 },
|
||||
{ 2130, 276, 130 }
|
||||
};
|
||||
|
||||
static const struct gain_coeff_t def_gain_coeff[] = {
|
||||
{ 3000, -1 }, /* 1x */
|
||||
{ 2000, 9800 }, /* 2x */
|
||||
{ 15, 60000 }, /* 64x */
|
||||
{ 0, 1300 } /* 128x */
|
||||
};
|
||||
|
||||
static const struct lux_cal_data_t def_lux_data = {
|
||||
.gain_coeff = def_gain_coeff,
|
||||
.opt_win_coeff = def_lux_coeff,
|
||||
.opt_win_coeff_count = ARRAY_SIZE(def_lux_coeff),
|
||||
.itime_cycle = BH1730_DEFAULT_INTEG_CYCLE,
|
||||
.mul = 1000
|
||||
};
|
||||
|
||||
struct bh1730_data {
|
||||
struct i2c_client *client;
|
||||
struct lux_cal_data_t cal;
|
||||
struct regulator *reg_vdd;
|
||||
struct regulator *reg_vid;
|
||||
enum bh1730_gain gain;
|
||||
bool powered;
|
||||
u32 itime_us;
|
||||
u32 tmt_us;
|
||||
};
|
||||
|
||||
static int bh1730_read_word(struct bh1730_data *bh1730, u8 reg)
|
||||
{
|
||||
int ret = i2c_smbus_read_word_data(bh1730->client,
|
||||
BH1730_CMD_BIT | reg);
|
||||
if (ret < 0)
|
||||
dev_err(&bh1730->client->dev,
|
||||
"i2c read failed error %d, register %01x\n",
|
||||
ret, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bh1730_write(struct bh1730_data *bh1730, u8 reg, u8 val)
|
||||
{
|
||||
int ret = i2c_smbus_write_byte_data(bh1730->client,
|
||||
BH1730_CMD_BIT | reg,
|
||||
val);
|
||||
if (ret < 0)
|
||||
dev_err(&bh1730->client->dev,
|
||||
"i2c write failed error %d, register %01x\n",
|
||||
ret, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bh1730_gain_multiplier(struct bh1730_data *bh1730)
|
||||
{
|
||||
switch (bh1730->gain) {
|
||||
case BH1730_GAIN_1X:
|
||||
return 1;
|
||||
case BH1730_GAIN_2X:
|
||||
return 2;
|
||||
case BH1730_GAIN_64X:
|
||||
return 64;
|
||||
case BH1730_GAIN_128X:
|
||||
return 128;
|
||||
}
|
||||
|
||||
dev_warn(&bh1730->client->dev,
|
||||
"invalid gain multiplier settings: %d\n", bh1730->gain);
|
||||
bh1730->gain = BH1730_GAIN_1X;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bh1730_set_gain(struct bh1730_data *bh1730, enum bh1730_gain gain)
|
||||
{
|
||||
int ret = bh1730_write(bh1730, BH1730_REG_GAIN, gain);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
bh1730->gain = gain;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bh1730_set_integration_time_cycle(struct bh1730_data *bh1730,
|
||||
u32 cycle)
|
||||
{
|
||||
int ret, itime;
|
||||
|
||||
itime = 256 - cycle;
|
||||
|
||||
/* ITIME == 0 is reserved for manual integration mode. */
|
||||
if (itime <= 0 || itime > 255) {
|
||||
dev_warn(&bh1730->client->dev,
|
||||
"integration time out of range: %d cycles\n", cycle);
|
||||
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
ret = bh1730_write(bh1730, BH1730_REG_TIMING, itime);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
bh1730->itime_us = BH1730_ITIME_TO_US * cycle;
|
||||
bh1730->tmt_us = bh1730->itime_us + BH1730_ADC_CALC_DELAY_US;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bh1730_adjust_gain(struct bh1730_data *bh1730)
|
||||
{
|
||||
int visible, ir, highest, gain, ret;
|
||||
|
||||
visible = bh1730_read_word(bh1730, BH1730_REG_DATA0LOW);
|
||||
if (visible < 0)
|
||||
return visible;
|
||||
|
||||
ir = bh1730_read_word(bh1730, BH1730_REG_DATA1LOW);
|
||||
if (ir < 0)
|
||||
return ir;
|
||||
|
||||
highest = max(visible, ir);
|
||||
|
||||
/* Adjust gain based on sensitivity calibration */
|
||||
gain = bh1730->gain;
|
||||
if (highest > bh1730->cal.gain_coeff[gain].fl &&
|
||||
gain != BH1730_GAIN_1X) {
|
||||
gain--; /* Decrease sensitivity */
|
||||
} else if (highest < bh1730->cal.gain_coeff[gain].cl &&
|
||||
gain != BH1730_GAIN_128X) {
|
||||
gain++; /* Increase sensitivity */
|
||||
}
|
||||
|
||||
if (gain != bh1730->gain) {
|
||||
ret = bh1730_set_gain(bh1730, gain);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
fsleep(bh1730->tmt_us);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bh1730_get_lux(struct bh1730_data *bh1730)
|
||||
{
|
||||
const struct opt_win_coeff_t *opt_win_coeff;
|
||||
int i, visible, ir;
|
||||
u64 lux = 0;
|
||||
|
||||
visible = bh1730_read_word(bh1730, BH1730_REG_DATA0LOW);
|
||||
|
||||
/* If visible is 0, skip calculations */
|
||||
if (visible <= 0)
|
||||
return visible;
|
||||
|
||||
ir = bh1730_read_word(bh1730, BH1730_REG_DATA1LOW);
|
||||
if (ir < 0)
|
||||
return ir;
|
||||
|
||||
/* Calibrate based on optical window */
|
||||
for (i = 0; i < bh1730->cal.opt_win_coeff_count; i++) {
|
||||
opt_win_coeff = &bh1730->cal.opt_win_coeff[i];
|
||||
if (1000 * ir / visible < opt_win_coeff->rc) {
|
||||
lux = ((u64)opt_win_coeff->cv * visible) -
|
||||
(opt_win_coeff->ci * ir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate lux */
|
||||
lux *= BH1730_DEFAULT_ITIME_MS;
|
||||
lux = div_u64(lux, bh1730_gain_multiplier(bh1730) * bh1730->itime_us);
|
||||
lux = div_u64(lux * bh1730->cal.mul, 1000);
|
||||
|
||||
if (lux > BH1730_MAX_MEASURED_LUX)
|
||||
lux = BH1730_MAX_MEASURED_LUX;
|
||||
|
||||
return (int)lux;
|
||||
}
|
||||
|
||||
static int bh1730_power_ctrl(struct bh1730_data *bh1730, bool enable)
|
||||
{
|
||||
struct device *dev = &bh1730->client->dev;
|
||||
int ret;
|
||||
|
||||
if (bh1730->powered == enable)
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
ret = regulator_enable(bh1730->reg_vdd);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable vdd: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_enable(bh1730->reg_vid);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable vid: %d\n", ret);
|
||||
regulator_disable(bh1730->reg_vdd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fsleep(BH1730_POWER_ON_DELAY_US);
|
||||
} else {
|
||||
regulator_disable(bh1730->reg_vid);
|
||||
regulator_disable(bh1730->reg_vdd);
|
||||
}
|
||||
|
||||
bh1730->powered = enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bh1730_power_on(struct bh1730_data *bh1730)
|
||||
{
|
||||
int ret = bh1730_power_ctrl(bh1730, true);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return bh1730_write(bh1730, BH1730_REG_CONTROL,
|
||||
BH1730_CONTROL_POWER | BH1730_CONTROL_ADC_EN);
|
||||
}
|
||||
|
||||
static int bh1730_init_config(struct bh1730_data *bh1730)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bh1730_set_gain(bh1730, BH1730_GAIN_64X);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return bh1730_set_integration_time_cycle(bh1730,
|
||||
bh1730->cal.itime_cycle);
|
||||
}
|
||||
|
||||
static int bh1730_power_off(struct bh1730_data *bh1730)
|
||||
{
|
||||
int ret = bh1730_write(bh1730, BH1730_REG_CONTROL, 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return bh1730_power_ctrl(bh1730, false);
|
||||
}
|
||||
|
||||
static int bh1730_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct bh1730_data *bh1730 = iio_priv(indio_dev);
|
||||
int data_reg, ret;
|
||||
|
||||
ret = bh1730_adjust_gain(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_PROCESSED:
|
||||
ret = bh1730_get_lux(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*val = ret;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
switch (chan->channel2) {
|
||||
case IIO_MOD_LIGHT_CLEAR:
|
||||
data_reg = BH1730_REG_DATA0LOW;
|
||||
break;
|
||||
case IIO_MOD_LIGHT_IR:
|
||||
data_reg = BH1730_REG_DATA1LOW;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = bh1730_read_word(bh1730, data_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ret * 1000 / bh1730_gain_multiplier(bh1730);
|
||||
*val = ret / 1000;
|
||||
*val2 = (ret % 1000) * 1000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_INT_TIME:
|
||||
*val = 0;
|
||||
*val2 = bh1730->itime_us;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int bh1730_parse_dt(struct bh1730_data *bh1730)
|
||||
{
|
||||
struct device *dev = &bh1730->client->dev;
|
||||
struct device_node *dn = dev->of_node;
|
||||
u32 *opt_win_coeff = NULL;
|
||||
u32 *gain_coeff = NULL;
|
||||
int opt_win_coeff_count, gain_coeff_count;
|
||||
u32 cycle = 0, mul = 0;
|
||||
|
||||
bh1730->cal = def_lux_data;
|
||||
|
||||
bh1730->reg_vdd = devm_regulator_get(dev, "als-vdd");
|
||||
if (IS_ERR(bh1730->reg_vdd))
|
||||
return dev_err_probe(dev, PTR_ERR(bh1730->reg_vdd),
|
||||
"failed to get als-vdd\n");
|
||||
|
||||
bh1730->reg_vid = devm_regulator_get(dev, "als-vid");
|
||||
if (IS_ERR(bh1730->reg_vid))
|
||||
return dev_err_probe(dev, PTR_ERR(bh1730->reg_vid),
|
||||
"failed to get als-vid\n");
|
||||
|
||||
if (!dn)
|
||||
goto out;
|
||||
|
||||
/* Get calibration */
|
||||
if (of_property_read_u32(dn, "rohm,integration-cycle", &cycle) ||
|
||||
of_property_read_u32(dn, "rohm,lux-multiplier", &mul) ||
|
||||
!cycle || !mul)
|
||||
goto out;
|
||||
|
||||
/* Get optical window coefficients */
|
||||
opt_win_coeff_count = of_property_count_u32_elems(dn, "rohm,opt-win-coeff");
|
||||
if (opt_win_coeff_count > 0 &&
|
||||
!(opt_win_coeff_count % (sizeof(struct opt_win_coeff_t) / sizeof(u32)))) {
|
||||
opt_win_coeff = devm_kcalloc(dev, opt_win_coeff_count,
|
||||
sizeof(u32), GFP_KERNEL);
|
||||
if (!opt_win_coeff)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_property_read_u32_array(dn, "rohm,opt-win-coeff",
|
||||
opt_win_coeff, opt_win_coeff_count))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get gain sensitivity coefficients, 2 for each gain supported */
|
||||
gain_coeff_count = of_property_count_u32_elems(dn, "rohm,gain-coeff");
|
||||
if (gain_coeff_count == 8) {
|
||||
gain_coeff = devm_kcalloc(dev, gain_coeff_count,
|
||||
sizeof(u32), GFP_KERNEL);
|
||||
if (!gain_coeff)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_property_read_u32_array(dn, "rohm,gain-coeff",
|
||||
gain_coeff, gain_coeff_count))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_win_coeff) {
|
||||
bh1730->cal.opt_win_coeff =
|
||||
(const struct opt_win_coeff_t *)opt_win_coeff;
|
||||
bh1730->cal.opt_win_coeff_count = opt_win_coeff_count /
|
||||
(sizeof(struct opt_win_coeff_t) / sizeof(u32));
|
||||
}
|
||||
|
||||
if (gain_coeff)
|
||||
bh1730->cal.gain_coeff = (const struct gain_coeff_t *)gain_coeff;
|
||||
|
||||
bh1730->cal.itime_cycle = cycle;
|
||||
bh1730->cal.mul = mul;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
dev_info(dev, "using default calibration\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_info bh1730_info = {
|
||||
.read_raw = bh1730_read_raw,
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec bh1730_channels[] = {
|
||||
{
|
||||
.type = IIO_LIGHT,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
|
||||
BIT(IIO_CHAN_INFO_INT_TIME),
|
||||
},
|
||||
{
|
||||
.type = IIO_INTENSITY,
|
||||
.modified = 1,
|
||||
.channel2 = IIO_MOD_LIGHT_CLEAR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
},
|
||||
{
|
||||
.type = IIO_INTENSITY,
|
||||
.modified = 1,
|
||||
.channel2 = IIO_MOD_LIGHT_IR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
},
|
||||
};
|
||||
|
||||
static void bh1730_power_off_action(void *data)
|
||||
{
|
||||
bh1730_power_off(data);
|
||||
}
|
||||
|
||||
static int bh1730_probe(struct i2c_client *client)
|
||||
{
|
||||
struct bh1730_data *bh1730;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_WORD_DATA))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*bh1730));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
bh1730 = iio_priv(indio_dev);
|
||||
bh1730->client = client;
|
||||
i2c_set_clientdata(client, indio_dev);
|
||||
|
||||
ret = bh1730_parse_dt(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = bh1730_power_on(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, bh1730_power_off_action,
|
||||
bh1730);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = bh1730_init_config(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
indio_dev->info = &bh1730_info;
|
||||
indio_dev->name = "bh1730";
|
||||
indio_dev->channels = bh1730_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(bh1730_channels);
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
return devm_iio_device_register(&client->dev, indio_dev);
|
||||
}
|
||||
|
||||
static int bh1730_suspend(struct device *dev)
|
||||
{
|
||||
struct bh1730_data *bh1730 = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
return bh1730_power_off(bh1730);
|
||||
}
|
||||
|
||||
static int bh1730_resume(struct device *dev)
|
||||
{
|
||||
struct bh1730_data *bh1730 = iio_priv(dev_get_drvdata(dev));
|
||||
int ret;
|
||||
|
||||
ret = bh1730_power_on(bh1730);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return bh1730_init_config(bh1730);
|
||||
}
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(bh1730_pm_ops, bh1730_suspend, bh1730_resume);
|
||||
|
||||
static const struct i2c_device_id bh1730_i2c_device_id[] = {
|
||||
{ BH1730_NAME },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bh1730_i2c_device_id);
|
||||
|
||||
static const struct of_device_id of_bh1730_match[] = {
|
||||
{ .compatible = "rohm,bh1730fvc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_bh1730_match);
|
||||
|
||||
static struct i2c_driver bh1730_driver = {
|
||||
.probe = bh1730_probe,
|
||||
.driver = {
|
||||
.name = BH1730_NAME,
|
||||
.of_match_table = of_bh1730_match,
|
||||
.pm = pm_sleep_ptr(&bh1730_pm_ops),
|
||||
},
|
||||
.id_table = bh1730_i2c_device_id,
|
||||
};
|
||||
module_i2c_driver(bh1730_driver);
|
||||
|
||||
MODULE_AUTHOR("CTCaer <ctcaer@gmail.com>");
|
||||
MODULE_DESCRIPTION("ROHM BH1730FVC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -221,8 +221,6 @@
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_TERM_EN BIT(18)
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_MODE_OVRD BIT(13)
|
||||
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL8(x) (0x47c + (x) * 0x40)
|
||||
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(x) (0x464 + (x) * 0x40)
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ BIT(0)
|
||||
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_TX_IDDQ_OVRD BIT(1)
|
||||
@@ -432,20 +430,6 @@ static struct init_data tegra210b01_usb3_pll_g1_init_data[] = {
|
||||
{.cfg_addr = 0x1E, .cfg_wdata = 0x0017},
|
||||
};
|
||||
|
||||
static struct init_data tegra210b01_usb3_lane_init_data[] = {
|
||||
{.cfg_addr = 0x1, .cfg_wdata = 0x0002},
|
||||
{.cfg_addr = 0x4, .cfg_wdata = 0x0032},
|
||||
{.cfg_addr = 0x7, .cfg_wdata = 0x0022},
|
||||
{.cfg_addr = 0x35, .cfg_wdata = 0x2587},
|
||||
{.cfg_addr = 0x49, .cfg_wdata = 0x0FC7},
|
||||
{.cfg_addr = 0x52, .cfg_wdata = 0x0001},
|
||||
{.cfg_addr = 0x53, .cfg_wdata = 0x3C0F},
|
||||
{.cfg_addr = 0x56, .cfg_wdata = 0xC00F},
|
||||
{.cfg_addr = 0x5D, .cfg_wdata = 0xFF07},
|
||||
{.cfg_addr = 0x5E, .cfg_wdata = 0x141A},
|
||||
{.cfg_addr = 0x97, .cfg_wdata = 0x0080},
|
||||
};
|
||||
|
||||
struct tegra210_xusb_fuse_calibration {
|
||||
u32 hs_curr_level[4];
|
||||
u32 hs_term_range_adj;
|
||||
@@ -546,31 +530,6 @@ static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void tegra210b01_usb3_lane_init(struct tegra_xusb_padctl *padctl)
|
||||
{
|
||||
struct tegra_xusb_lane *lane;
|
||||
unsigned int i, j;
|
||||
u32 value;
|
||||
|
||||
for (i = 0; i < padctl->pcie->soc->num_lanes; i++) {
|
||||
if (!padctl->pcie->lanes[i])
|
||||
continue;
|
||||
|
||||
lane = phy_get_drvdata(padctl->pcie->lanes[i]);
|
||||
if (!tegra_xusb_lane_check(lane, "usb3-ss"))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(tegra210b01_usb3_lane_init_data); j++) {
|
||||
value = CFG_ADDR(tegra210b01_usb3_lane_init_data[j].cfg_addr);
|
||||
value |= CFG_WDATA(tegra210b01_usb3_lane_init_data[j].cfg_wdata);
|
||||
value |= CFG_RESET;
|
||||
value |= CFG_WS;
|
||||
padctl_writel(padctl, value,
|
||||
XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL8(lane->index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* must be called under padctl->lock */
|
||||
static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
|
||||
{
|
||||
@@ -611,24 +570,22 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
|
||||
padctl_writel(padctl, value,
|
||||
XUSB_PADCTL_UPHY_PLL_S0_CTL10);
|
||||
}
|
||||
|
||||
tegra210b01_usb3_lane_init(padctl);
|
||||
} else {
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
|
||||
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
|
||||
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
|
||||
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT);
|
||||
value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
|
||||
}
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
|
||||
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
|
||||
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
|
||||
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT);
|
||||
value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL <<
|
||||
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
|
||||
value |= XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
|
||||
@@ -2210,10 +2167,7 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
|
||||
if (submode == USB_ROLE_HOST) {
|
||||
tegra210_xusb_padctl_id_override(padctl, true);
|
||||
|
||||
if (!port->supply_enabled) {
|
||||
err = regulator_enable(port->supply);
|
||||
port->supply_enabled = !err;
|
||||
}
|
||||
err = regulator_enable(port->supply);
|
||||
} else if (submode == USB_ROLE_DEVICE) {
|
||||
tegra210_xusb_padctl_vbus_override(padctl, true);
|
||||
} else if (submode == USB_ROLE_NONE) {
|
||||
@@ -2222,10 +2176,8 @@ static int tegra210_usb2_phy_set_mode(struct phy *phy, enum phy_mode mode,
|
||||
* USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
|
||||
* be enabled.
|
||||
*/
|
||||
if (port->supply_enabled) {
|
||||
if (regulator_is_enabled(port->supply))
|
||||
regulator_disable(port->supply);
|
||||
port->supply_enabled = false;
|
||||
}
|
||||
|
||||
tegra210_xusb_padctl_id_override(padctl, false);
|
||||
tegra210_xusb_padctl_vbus_override(padctl, false);
|
||||
|
||||
@@ -314,7 +314,6 @@ struct tegra_xusb_usb2_port {
|
||||
struct tegra_xusb_port base;
|
||||
|
||||
struct regulator *supply;
|
||||
bool supply_enabled;
|
||||
enum usb_dr_mode mode;
|
||||
bool internal;
|
||||
int usb3_port_fake;
|
||||
|
||||
@@ -466,7 +466,8 @@ struct tegra_pmc_soc {
|
||||
bool has_usb_sleepwalk;
|
||||
bool supports_core_domain;
|
||||
bool has_single_mmio_aperture;
|
||||
bool has_panic_notifier;
|
||||
|
||||
bool cboot_panic_notifier;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1365,6 +1366,7 @@ static int tegra_pmc_panic_handler(struct notifier_block *this,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
tegra_pmc_writel(pmc, KERNEL_PANIC_MAGIC, PMC_SCRATCH37);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@@ -3565,7 +3567,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
if (pmc->soc->has_panic_notifier) {
|
||||
if (pmc->soc->cboot_panic_notifier) {
|
||||
pmc->panic_notifier.notifier_call = tegra_pmc_panic_handler;
|
||||
pmc->panic_notifier.priority = INT_MAX-1;
|
||||
|
||||
@@ -4402,7 +4404,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
.has_panic_notifier = true,
|
||||
.cboot_panic_notifier = true,
|
||||
.has_bootrom_command = true,
|
||||
};
|
||||
|
||||
@@ -4465,7 +4467,7 @@ static const struct tegra_pmc_soc tegra210b01_pmc_soc = {
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
.has_panic_notifier = true,
|
||||
.cboot_panic_notifier = true,
|
||||
.has_bootrom_command = true,
|
||||
};
|
||||
|
||||
|
||||
@@ -961,9 +961,7 @@ static void bm92t_port_set_init_state(struct work_struct *work)
|
||||
"port is set to init state\n");
|
||||
|
||||
msleep(100); /* Wait a bit */
|
||||
disable_irq(info->i2c_client->irq);
|
||||
if (!queue_work(info->event_wq, &info->work))
|
||||
enable_irq(info->i2c_client->irq);
|
||||
queue_work(info->event_wq, &info->work);
|
||||
}
|
||||
|
||||
static bool bm92t_check_pdo(struct bm92t_info *info)
|
||||
@@ -1885,8 +1883,6 @@ ret:
|
||||
bm92t_read_reg(info, UNKOWN_1C_REG, (void *)&dp, sizeof(dp));
|
||||
bm92t_read_reg(info, UNKOWN_1D_REG, (void *)&dp, sizeof(dp));
|
||||
}
|
||||
|
||||
enable_irq(info->i2c_client->irq);
|
||||
}
|
||||
|
||||
static irqreturn_t bm92t_interrupt_handler(int irq, void *handle)
|
||||
@@ -1894,8 +1890,7 @@ static irqreturn_t bm92t_interrupt_handler(int irq, void *handle)
|
||||
struct bm92t_info *info = handle;
|
||||
|
||||
disable_irq_nosync(info->i2c_client->irq);
|
||||
if (!queue_work(info->event_wq, &info->work))
|
||||
enable_irq(info->i2c_client->irq);
|
||||
queue_work(info->event_wq, &info->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -2151,7 +2146,7 @@ static ssize_t bm92t_cmd_write(struct file *file,
|
||||
|
||||
ret = kstrtouint(buf, 0, &val);
|
||||
|
||||
if (!ret) {
|
||||
if (ret == 1) {
|
||||
cmd = val;
|
||||
bm92t_send_cmd(info, &cmd);
|
||||
} else {
|
||||
@@ -2183,7 +2178,7 @@ static ssize_t bm92t_usbhub_dp_sleep_write(struct file *file,
|
||||
|
||||
ret = kstrtouint(buf, 0, &val);
|
||||
|
||||
if (!ret) {
|
||||
if (ret == 1) {
|
||||
bm92t_usbhub_dp_sleep(info, val ? true : false);
|
||||
} else {
|
||||
dev_err(&info->i2c_client->dev, "Syntax is: 0 or number\n");
|
||||
@@ -2522,8 +2517,11 @@ static int bm92t_probe(struct i2c_client *client)
|
||||
if (client->irq > 0) {
|
||||
/*
|
||||
* Level-triggered (active-low) IRQ wired to BM92T36 ALERT.
|
||||
* The IRQ stays disabled while the event work runs i2c reads
|
||||
* and is re-enabled once the controller's status is cleared.
|
||||
* Use a threaded handler with IRQF_ONESHOT so the line is
|
||||
* masked while bm92t_interrupt_handler runs i2c reads, then
|
||||
* re-enabled after the work clears the controller's status.
|
||||
* Without IRQF_ONESHOT this would re-enter immediately on
|
||||
* the still-asserted line and "irq nobody cared" disable it.
|
||||
*/
|
||||
if (request_threaded_irq(client->irq, NULL,
|
||||
bm92t_interrupt_handler,
|
||||
|
||||
Reference in new issue
Block a user