Skip to content

drivers: video: mt9m114: Add vertical and horizontal flip control #81830

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions drivers/video/mt9m114.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <zephyr/logging/log.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/video.h>
#include <zephyr/drivers/video-controls.h>
#include <zephyr/drivers/i2c.h>

LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL);
Expand All @@ -31,6 +32,7 @@ LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL);
#define MT9M114_CAM_SENSOR_CFG_Y_ADDR_END 0xC804
#define MT9M114_CAM_SENSOR_CFG_X_ADDR_END 0xC806
#define MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW 0xC818
#define MT9M114_CAM_SENSOR_CTRL_READ_MODE 0xC834
#define MT9M114_CAM_CROP_WINDOW_WIDTH 0xC858
#define MT9M114_CAM_CROP_WINDOW_HEIGHT 0xC85A
#define MT9M114_CAM_OUTPUT_WIDTH 0xC868
Expand All @@ -53,6 +55,10 @@ LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL);
#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV (0 << 8)
#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB (1 << 8)

/* Camera control masks */
#define MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN BIT(0)
#define MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN BIT(1)

struct mt9m114_config {
struct i2c_dt_spec i2c;
};
Expand Down Expand Up @@ -261,20 +267,21 @@ static int mt9m114_read_reg(const struct device *dev, uint16_t reg_addr, uint8_t
return 0;
}

static int mt9m114_modify_reg(const struct device *dev, const uint16_t addr, const uint8_t mask,
const uint8_t val)
static int mt9m114_modify_reg(const struct device *dev, const uint16_t addr,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the extension of mt9m114_modify_reg() should go into a separate commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, I should create a separate commit for it, merge it and then carry on with this PR. Do you agree?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, just split the current commit into 2 commits then force-push in this same PR.

uint8_t reg_size, const uint32_t mask, const uint32_t val)
{
uint8_t oldVal;
uint8_t newVal;
int ret = mt9m114_read_reg(dev, addr, sizeof(oldVal), &oldVal);
uint32_t oldVal = 0;
uint32_t newVal = 0;

int ret = mt9m114_read_reg(dev, addr, reg_size, &oldVal);

if (ret) {
return ret;
}

newVal = (oldVal & ~mask) | (val & mask);

return mt9m114_write_reg(dev, addr, sizeof(newVal), &newVal);
return mt9m114_write_reg(dev, addr, reg_size, &newVal);
}

static int mt9m114_write_all(const struct device *dev, struct mt9m114_reg *reg)
Expand All @@ -297,15 +304,15 @@ static int mt9m114_write_all(const struct device *dev, struct mt9m114_reg *reg)

static int mt9m114_software_reset(const struct device *dev)
{
int ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 0x01, 0x01);
int ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 2, 0x01, 0x01);

if (ret) {
return ret;
}

k_sleep(K_MSEC(1));

ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 0x01, 0x00);
ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 2, 0x01, 0x00);
if (ret) {
return ret;
}
Expand Down Expand Up @@ -461,12 +468,40 @@ static int mt9m114_get_caps(const struct device *dev, enum video_endpoint_id ep,
return 0;
}

static int mt9m114_set_ctrl(const struct device *dev, unsigned int cid, void *value)
{
int ret = 0;

switch (cid) {
case VIDEO_CID_HFLIP:
ret = mt9m114_modify_reg(dev, MT9M114_CAM_SENSOR_CTRL_READ_MODE, 2,
MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN,
(int)value ? MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN : 0);
break;
case VIDEO_CID_VFLIP:
ret = mt9m114_modify_reg(dev, MT9M114_CAM_SENSOR_CTRL_READ_MODE, 2,
MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN,
(int)value ? MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN : 0);
break;
default:
return -ENOTSUP;
}

if (ret < 0) {
return ret;
}

/* Apply Config */
return mt9m114_set_state(dev, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
}

static DEVICE_API(video, mt9m114_driver_api) = {
.set_format = mt9m114_set_fmt,
.get_format = mt9m114_get_fmt,
.get_caps = mt9m114_get_caps,
.stream_start = mt9m114_stream_start,
.stream_stop = mt9m114_stream_stop,
.set_ctrl = mt9m114_set_ctrl,
};

static int mt9m114_init(const struct device *dev)
Expand Down
Loading