From: Antonio Ospite <ospite@studenti.unina.it>
Date: Mon, 20 Feb 2012 12:37:20 +0000 (+0100)
Subject: am7xxx: implement support for the AM7XXX_PACKET_TYPE_ZOOM
X-Git-Tag: v0.1.3~16^2~6
X-Git-Url: https://git.ao2.it/libam7xxx.git/commitdiff_plain/90247e36e90bebe6c8b80393d2a037b054808597?hp=--cc

am7xxx: implement support for the AM7XXX_PACKET_TYPE_ZOOM

The info has been guessed from the windows drivers, it may be imprecise
and incomplete.
---

90247e36e90bebe6c8b80393d2a037b054808597
diff --git a/src/am7xxx.c b/src/am7xxx.c
index 24b2b50..5481075 100644
--- a/src/am7xxx.c
+++ b/src/am7xxx.c
@@ -116,7 +116,7 @@ typedef enum {
 	AM7XXX_PACKET_TYPE_DEVINFO = 0x01,
 	AM7XXX_PACKET_TYPE_IMAGE   = 0x02,
 	AM7XXX_PACKET_TYPE_POWER   = 0x04,
-	AM7XXX_PACKET_TYPE_UNKNOWN = 0x05,
+	AM7XXX_PACKET_TYPE_ZOOM    = 0x05,
 } am7xxx_packet_type;
 
 struct am7xxx_generic_header {
@@ -146,6 +146,11 @@ struct am7xxx_power_header {
 	uint32_t bit0;
 };
 
+struct am7xxx_zoom_header {
+	uint32_t bit1;
+	uint32_t bit0;
+};
+
 /*
  * Examples of packet headers:
  *
@@ -171,6 +176,7 @@ struct am7xxx_header {
 		struct am7xxx_devinfo_header devinfo;
 		struct am7xxx_image_header image;
 		struct am7xxx_power_header power;
+		struct am7xxx_zoom_header zoom;
 	} header_data;
 };
 
@@ -211,6 +217,16 @@ static void debug_dump_power_header(am7xxx_context *ctx, struct am7xxx_power_hea
 	debug(ctx, "\tbit0: 0x%08x (%u)\n", p->bit0, p->bit0);
 }
 
+static void debug_dump_zoom_header(am7xxx_context *ctx, struct am7xxx_zoom_header *z)
+{
+	if (ctx == NULL || z == NULL)
+		return;
+
+	debug(ctx, "Zoom header:\n");
+	debug(ctx, "\tbit1: 0x%08x (%u)\n", z->bit1, z->bit1);
+	debug(ctx, "\tbit0: 0x%08x (%u)\n", z->bit0, z->bit0);
+}
+
 static void debug_dump_header(am7xxx_context *ctx, struct am7xxx_header *h)
 {
 	if (ctx == NULL || h == NULL)
@@ -236,6 +252,10 @@ static void debug_dump_header(am7xxx_context *ctx, struct am7xxx_header *h)
 		debug_dump_power_header(ctx, &(h->header_data.power));
 		break;
 
+	case AM7XXX_PACKET_TYPE_ZOOM:
+		debug_dump_zoom_header(ctx, &(h->header_data.zoom));
+		break;
+
 	default:
 		debug(ctx, "Packet type not supported!\n");
 		break;
@@ -879,3 +899,47 @@ AM7XXX_PUBLIC int am7xxx_set_power_mode(am7xxx_device *dev, am7xxx_power_mode mo
 
 	return 0;
 }
+
+AM7XXX_PUBLIC int am7xxx_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom)
+{
+	int ret;
+	struct am7xxx_header h = {
+		.packet_type     = AM7XXX_PACKET_TYPE_ZOOM,
+		.direction       = AM7XXX_DIRECTION_OUT,
+		.header_data_len = sizeof(struct am7xxx_zoom_header),
+		.unknown2        = 0x3e,
+		.unknown3        = 0x10,
+	};
+
+	switch(zoom) {
+	case AM7XXX_ZOOM_ORIGINAL:
+		h.header_data.zoom.bit1 = 0;
+		h.header_data.zoom.bit0 = 0;
+		break;
+
+	case AM7XXX_ZOOM_H:
+		h.header_data.zoom.bit1 = 0;
+		h.header_data.zoom.bit0 = 1;
+		break;
+
+	case AM7XXX_ZOOM_H_V:
+		h.header_data.zoom.bit1 = 1;
+		h.header_data.zoom.bit0 = 0;
+		break;
+
+	case AM7XXX_ZOOM_TEST:
+		h.header_data.zoom.bit1 = 1;
+		h.header_data.zoom.bit0 = 1;
+		break;
+
+	default:
+		error(dev->ctx, "Unsupported zoom mode.\n");
+		return -EINVAL;
+	};
+
+	ret = send_header(dev, &h);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
diff --git a/src/am7xxx.h b/src/am7xxx.h
index 51f9324..885cef2 100644
--- a/src/am7xxx.h
+++ b/src/am7xxx.h
@@ -105,6 +105,24 @@ typedef enum {
 } am7xxx_power_mode;
 
 /**
+ * The display zoom modes.
+ *
+ * An am7xxx device can display images using several zoom modes.
+ *
+ * @note Changing the zoom mode can change the aspect ratio of the displayed
+ * image.
+ *
+ * @note On the zoom test screen the version of the firmware running on the
+ * device is shown as well (e.g SPI_V21.0.0_2011.03.18).
+ */
+typedef enum {
+	AM7XXX_ZOOM_ORIGINAL = 0, /**< Original Size, as retrieved via #am7xxx_device_info. */
+	AM7XXX_ZOOM_H        = 1, /**< Zoom 1: H Scale (changes aspect ratio). */
+	AM7XXX_ZOOM_H_V      = 2, /**< Zoom 2: H/V Scale (changes aspect ratio). */
+	AM7XXX_ZOOM_TEST     = 3, /**< Zoom test screen, the firmware version is shown as well. */
+} am7xxx_zoom_mode;
+
+/**
  * Initialize the library context and data structures, and scan for devices.
  *
  * @param[out] ctx A pointer to the context the library will be used in.
@@ -238,6 +256,26 @@ int am7xxx_send_image(am7xxx_device *dev,
  */
 int am7xxx_set_power_mode(am7xxx_device *dev, am7xxx_power_mode mode);
 
+/**
+ * Set the zoom mode of an am7xxx device.
+ *
+ * @note When setting the mode to AM7XXX_ZOOM_TEST, the calling program might
+ * want to skip displaying actual images.
+ *
+ * @note It looks like that power mode and zoom mode are related somehow wrt.
+ * resetting the operational mode after AM7XXX_POWER_OFF, applications can
+ * restore the display properly using this combination:
+ *  - Off: power mode 0, zoom mode 3
+ *  - On: power mode != 0, zoom mode != 3
+ *
+ * @param[in] dev A pointer to the structure representing the device to set zoom mode to
+ * @param[in] zoom The zoom mode to put the device in (see #am7xxx_zoom_mode enum)
+ *
+ * @return 0 on success, a negative value on error
+ *
+ */
+int am7xxx_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom);
+
 #ifdef __cplusplus
 }
 #endif