summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xaudio/audio_hw.c9
-rw-r--r--device.mk3
-rwxr-xr-xinit.tuna.rc7
-rw-r--r--kernelbin3844532 -> 3847864 bytes
-rw-r--r--libsensors/LightSensor.cpp43
-rw-r--r--libsensors/LightSensor.h3
-rw-r--r--libsensors/sensors.cpp2
-rw-r--r--nfc/Android.mk25
-rw-r--r--nfc/nfc_hw.c139
-rw-r--r--overlay/frameworks/base/core/res/res/values/config.xml10
-rw-r--r--overlay/packages/apps/Settings/res/values-be/arrays.xml31
-rw-r--r--overlay/packages/apps/Settings/res/values-et/arrays.xml31
-rw-r--r--reflash-bootloader/Android.mk10
-rwxr-xr-xreflash-bootloader/build-image.sh14
-rw-r--r--reflash-bootloader/reflash-bootloader.c359
15 files changed, 633 insertions, 53 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 2a58f4f..55d221d 100755
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -697,6 +697,7 @@ static void set_incall_device(struct tuna_audio_device *adev)
break;
case AUDIO_DEVICE_OUT_SPEAKER:
case AUDIO_DEVICE_OUT_AUX_DIGITAL:
+ case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
device_type = SOUND_AUDIO_PATH_SPEAKER;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADSET:
@@ -951,9 +952,11 @@ static void select_output_device(struct tuna_audio_device *adev)
break;
case TTY_MODE_OFF:
default:
- /* force speaker on when in call and HDMI is selected as voice DL audio
- * cannot be routed to HDMI by ABE */
- if (adev->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+ /* force speaker on when in call and HDMI or S/PDIF is selected
+ * as voice DL audio cannot be routed there by ABE */
+ if (adev->devices &
+ (AUDIO_DEVICE_OUT_AUX_DIGITAL |
+ AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))
speaker_on = 1;
break;
}
diff --git a/device.mk b/device.mk
index 300a973..fa2aa8d 100644
--- a/device.mk
+++ b/device.mk
@@ -44,6 +44,9 @@ PRODUCT_PACKAGES += \
libinvensense_mpl
PRODUCT_PACKAGES += \
+ nfc.tuna
+
+PRODUCT_PACKAGES += \
audio.primary.tuna \
audio.a2dp.default \
libaudioutils
diff --git a/init.tuna.rc b/init.tuna.rc
index bcb8be7..bdcedac 100755
--- a/init.tuna.rc
+++ b/init.tuna.rc
@@ -45,10 +45,6 @@ on boot
write /sys/devices/system/cpu/cpufreq/interactive/timer_rate 80000
write /sys/devices/system/cpu/cpufreq/interactive/min_sample_time 10000
-# autosuspend root hubs immediatly after attached devices
- write /sys/bus/usb/devices/usb1/power/autosuspend_delay_ms 0
- write /sys/bus/usb/devices/usb2/power/autosuspend_delay_ms 0
-
on fs
mkdir /factory 0775 radio radio
mount ext4 /dev/block/platform/omap/omap_hsmmc.0/by-name/system /system wait ro
@@ -146,7 +142,8 @@ service pvrsrvinit /vendor/bin/pvrsrvinit
# create filesystems if necessary
service setup_fs /system/bin/setup_fs \
/dev/block/platform/omap/omap_hsmmc.0/by-name/cache \
- /dev/block/platform/omap/omap_hsmmc.0/by-name/userdata
+ /dev/block/platform/omap/omap_hsmmc.0/by-name/userdata \
+ /dev/block/platform/omap/omap_hsmmc.0/by-name/efs
class core
user root
group root
diff --git a/kernel b/kernel
index eff6df0..56213e4 100644
--- a/kernel
+++ b/kernel
Binary files differ
diff --git a/libsensors/LightSensor.cpp b/libsensors/LightSensor.cpp
index 15ae4e2..29b222b 100644
--- a/libsensors/LightSensor.cpp
+++ b/libsensors/LightSensor.cpp
@@ -31,46 +31,17 @@ LightSensor::LightSensor()
{
mPendingEvent.sensor = ID_L;
mPendingEvent.type = SENSOR_TYPE_LIGHT;
- mPreviousLight = -1;
-}
-
-int LightSensor::handleEnable(int en) {
- mPreviousLight = -1;
- return 0;
}
bool LightSensor::handleEvent(input_event const *event) {
if (event->value == -1) {
return false;
}
- mPendingEvent.light = indexToValue(event->value);
- if (mPendingEvent.light != mPreviousLight) {
- mPreviousLight = mPendingEvent.light;
- return true;
- }
- return false;
-}
-
-float LightSensor::indexToValue(size_t index) const {
- /* Driver gives a rolling average adc value. We convert it lux levels. */
- static const struct adcToLux {
- size_t adc_value;
- float lux_value;
- } adcToLux[] = {
- { 50, 10.0 }, /* from 0 - 50 adc, we map to 10.0 lux */
- { 280, 160.0 }, /* from 51 - 280 adc, we map to 160.0 lux */
- { 320, 225.0 }, /* from 281 - 320 adc, we map to 225.0 lux */
- { 350, 320.0 }, /* from 321 - 350 adc, we map to 320.0 lux */
- { 400, 640.0 }, /* from 351 - 400 adc, we map to 640.0 lux */
- { 520, 1280.0 }, /* from 401 - 520 adc, we map to 1280.0 lux */
- { 590, 2600.0 }, /* from 521 - 590 adc, we map to 2600.0 lux */
- { 1024, 10240.0 }, /* from 591 - 1024 adc, we map to 10240.0 lux */
- };
- size_t i;
- for (i = 0; i < ARRAY_SIZE(adcToLux); i++) {
- if (index <= adcToLux[i].adc_value) {
- return adcToLux[i].lux_value;
- }
- }
- return adcToLux[ARRAY_SIZE(adcToLux)-1].lux_value;
+ // Convert adc value to lux assuming:
+ // I = 10 * log(Ev) uA
+ // R = 24kOhm
+ // Max adc value 1023 = 1.25V
+ // 1/4 of light reaches sensor
+ mPendingEvent.light = powf(10, event->value * (125.0f / 1023.0f / 24.0f)) * 4;
+ return true;
}
diff --git a/libsensors/LightSensor.h b/libsensors/LightSensor.h
index ed3b435..f5f8af0 100644
--- a/libsensors/LightSensor.h
+++ b/libsensors/LightSensor.h
@@ -32,10 +32,7 @@ struct input_event;
class LightSensor:public SamsungSensorBase {
- float mPreviousLight;
- virtual int handleEnable(int en);
virtual bool handleEvent(input_event const * event);
- float indexToValue(size_t index) const;
public:
LightSensor();
};
diff --git a/libsensors/sensors.cpp b/libsensors/sensors.cpp
index 57b1aa8..156f08d 100644
--- a/libsensors/sensors.cpp
+++ b/libsensors/sensors.cpp
@@ -80,7 +80,7 @@ static struct sensor_t sSensorList[LOCAL_SENSORS + MPLSensor::numSensors] = {
{ "GP2A Light sensor",
"Sharp",
1, SENSORS_LIGHT_HANDLE,
- SENSOR_TYPE_LIGHT, 3000.0f, 1.0f, 0.75f, 0, { } },
+ SENSOR_TYPE_LIGHT, powf(10, 125.0f/ 24.0f) * 4, 1.0f, 0.75f, 0, { } },
{ "GP2A Proximity sensor",
"Sharp",
1, SENSORS_PROXIMITY_HANDLE,
diff --git a/nfc/Android.mk b/nfc/Android.mk
new file mode 100644
index 0000000..000b5ae
--- /dev/null
+++ b/nfc/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := nfc.tuna
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SRC_FILES := nfc_hw.c
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/nfc/nfc_hw.c b/nfc/nfc_hw.c
new file mode 100644
index 0000000..4b4dda5
--- /dev/null
+++ b/nfc/nfc_hw.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <errno.h>
+#include <string.h>
+
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+
+static uint8_t pn544_eedata_settings[][4] = {
+ // DIFFERENTIAL_ANTENNA
+
+ // RF Settings
+ {0x00,0x9B,0xD1,0x0D} // Tx consumption higher than 0x0D (average 50mA)
+ ,{0x00,0x9B,0xD2,0x24} // GSP setting for this threshold
+ ,{0x00,0x9B,0xD3,0x0A} // Tx consumption higher than 0x0A (average 40mA)
+ ,{0x00,0x9B,0xD4,0x22} // GSP setting for this threshold
+ ,{0x00,0x9B,0xD5,0x08} // Tx consumption higher than 0x08 (average 30mA)
+ ,{0x00,0x9B,0xD6,0x1E} // GSP setting for this threshold
+ ,{0x00,0x9B,0xDD,0x1C} // GSP setting for this threshold
+ ,{0x00,0x9B,0x84,0x13} // ANACM2 setting
+ ,{0x00,0x99,0x81,0x7F} // ANAVMID setting PCD
+ ,{0x00,0x99,0x31,0x70} // ANAVMID setting PICC
+ ,{0x00,0x99,0x29,0xF6} // Load modulation amplitude fine tuning (???)
+
+ // Enable PBTF
+ ,{0x00,0x98,0x00,0x3F} // SECURE_ELEMENT_CONFIGURATION - No Secure Element
+ ,{0x00,0x9F,0x09,0x00} // SWP_PBTF_RFU
+ ,{0x00,0x9F,0x0A,0x05} // SWP_PBTF_RFLD --> RFLEVEL Detector for PBTF
+ ,{0x00,0x9E,0xD1,0xA1} //
+
+ // Change RF Level Detector ANARFLDWU
+ ,{0x00,0x99,0x23,0x00} // Default Value is 0x01
+
+ // Low-power polling
+ ,{0x00,0x9E,0x74,0xB0} // Default Value is 0x00, bits 0->2: sensitivity (0==max, 6==min),
+ // bit 3: RFU,
+ // bits 4,5 hybrid low-power: # of low-power polls per regular poll
+ // bit 6: RFU
+ // bit 7: (0 -> disabled, 1 -> enabled)
+ ,{0x00,0x9E,0x7D,0xB0} // bits 0->3: RFU,
+ // bits 4,5: # retries after low power detection
+ // 0=1 retry, 1=2 retry, 2=3 retry, 3=4 retry
+ // bit 6: RFU,
+ // bit 7: Enable or disable retry mechanism (0: disable, 1: enable)
+ ,{0x00,0x9F,0x28,0x01} // bits 0->7: # of measurements per low-power poll
+
+ // Polling Loop - Card Emulation Timeout
+ ,{0x00,0x9F,0x35,0x14} // Time for which PN544 stays in Card Emulation mode after leaving RF field
+ ,{0x00,0x9F,0x36,0x60} // Default value 0x0411 = 50 ms ---> New Value : 0x1460 = 250 ms
+
+ //LLC Timer
+ ,{0x00,0x9C,0x31,0x00} // Guard host time-out in ms (MSB)
+ ,{0x00,0x9C,0x32,0xC8} // Guard host time-out in ms (LSB)
+ ,{0x00,0x9C,0x19,0x40} // Max RX retry (PN544=>host?)
+ ,{0x00,0x9C,0x1A,0x40} // Max TX retry (PN544=>host?)
+
+ ,{0x00,0x9C,0x0C,0x00} //
+ ,{0x00,0x9C,0x0D,0x00} //
+ ,{0x00,0x9C,0x12,0x00} //
+ ,{0x00,0x9C,0x13,0x00} //
+
+ //WTX for LLCP communication
+ ,{0x00,0x98,0xA2,0x0E} // Max value: 14 (default value: 09)
+
+ //SE GPIO
+ ,{0x00, 0x98, 0x93, 0x40}
+
+ // Set NFCT ATQA
+ ,{0x00, 0x98, 0x7D, 0x02}
+ ,{0x00, 0x98, 0x7E, 0x00}
+
+ // Enable CEA detection mechanism
+ ,{0x00, 0x9F, 0xC8, 0x01}
+ // Set NFC-F poll RC=0x00
+ ,{0x00, 0x9F, 0x9A, 0x00}
+ // Setting for EMD support for ISO 14443-4 Reader
+ ,{0x00,0x9F,0x09,0x00} // 0x00 - Disable EMD support, 0x01 - Enable EMD support
+};
+
+static int pn544_close(hw_device_t *dev) {
+ free(dev);
+
+ return 0;
+}
+
+/*
+ * Generic device handling
+ */
+
+static int nfc_open(const hw_module_t* module, const char* name,
+ hw_device_t** device) {
+ if (strcmp(name, NFC_PN544_CONTROLLER) == 0) {
+ nfc_pn544_device_t *dev = calloc(1, sizeof(nfc_pn544_device_t));
+
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t*) module;
+ dev->common.close = pn544_close;
+
+ dev->num_eeprom_settings = sizeof(pn544_eedata_settings) / 4;
+ dev->eeprom_settings = (uint8_t*)pn544_eedata_settings;
+ dev->linktype = PN544_LINK_TYPE_UART;
+ dev->device_node = "/dev/ttyO3";
+ dev->enable_i2c_workaround = 0;
+ *device = (hw_device_t*) dev;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+}
+
+static struct hw_module_methods_t nfc_module_methods = {
+ .open = nfc_open,
+};
+
+struct nfc_module_t HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = NFC_HARDWARE_MODULE_ID,
+ .name = "Tuna NFC HW HAL",
+ .author = "The Android Open Source Project",
+ .methods = &nfc_module_methods,
+ },
+};
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 55c3d45..5110ae8 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -64,11 +64,11 @@
Must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLevels">
- <item>100</item>
- <item>200</item>
- <item>400</item>
- <item>1000</item>
- <item>3000</item>
+ <item>7</item>
+ <item>107</item>
+ <item>244</item>
+ <item>440</item>
+ <item>4080</item>
</integer-array>
<!-- Array of output values for LCD backlight corresponding to the LUX values
diff --git a/overlay/packages/apps/Settings/res/values-be/arrays.xml b/overlay/packages/apps/Settings/res/values-be/arrays.xml
new file mode 100644
index 0000000..e1dfcf3
--- /dev/null
+++ b/overlay/packages/apps/Settings/res/values-be/arrays.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2011 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="screen_timeout_entries">
+ <item msgid="5314770629356662739">"15 секунд"</item>
+ <item msgid="8672738773876256432">"30 секунд"</item>
+ <item msgid="465923292941002466">"1 хвіліна"</item>
+ <item msgid="7955177189296850016">"2 хвіліны"</item>
+ <item msgid="1244255986255344525">"5 хвілін"</item>
+ <item msgid="294890536998091748">"10 хвілін"</item>
+ </string-array>
+</resources>
diff --git a/overlay/packages/apps/Settings/res/values-et/arrays.xml b/overlay/packages/apps/Settings/res/values-et/arrays.xml
new file mode 100644
index 0000000..bb3352e
--- /dev/null
+++ b/overlay/packages/apps/Settings/res/values-et/arrays.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2011 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="screen_timeout_entries">
+ <item msgid="5314770629356662739">"15 sekundit"</item>
+ <item msgid="8672738773876256432">"30 sekundit"</item>
+ <item msgid="465923292941002466">"1 minut"</item>
+ <item msgid="7955177189296850016">"2 minutit"</item>
+ <item msgid="1244255986255344525">"5 minutit"</item>
+ <item msgid="294890536998091748">"10 minutit"</item>
+ </string-array>
+</resources>
diff --git a/reflash-bootloader/Android.mk b/reflash-bootloader/Android.mk
new file mode 100644
index 0000000..c7a9e54
--- /dev/null
+++ b/reflash-bootloader/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := reflash-bootloader.c
+LOCAL_MODULE = tuna-reflash-bootloader
+LOCAL_MODULE_TAGS := optional
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_STATIC_LIBRARIES := libc
+include $(BUILD_EXECUTABLE)
diff --git a/reflash-bootloader/build-image.sh b/reflash-bootloader/build-image.sh
new file mode 100755
index 0000000..7b0edf5
--- /dev/null
+++ b/reflash-bootloader/build-image.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+DIR=/tmp/reflash_bootloader.$$
+RAMDISK=/tmp/ramdisk.$$.img
+
+mkdir ${DIR}
+cp ${OUT}/system/bin/tuna-reflash-bootloader ${DIR}/init
+cp ${ANDROID_BUILD_TOP}/vendor/samsung/tuna/bootloader.img ${DIR}/bootloader.img
+mkbootfs ${DIR} | minigzip > ${RAMDISK}
+mkbootimg --kernel ${OUT}/kernel --ramdisk ${RAMDISK} -o tuna-reflash-bootloader.img
+rm ${DIR}/init
+rm ${DIR}/bootloader.img
+rmdir ${DIR}
+rm ${RAMDISK}
diff --git a/reflash-bootloader/reflash-bootloader.c b/reflash-bootloader/reflash-bootloader.c
new file mode 100644
index 0000000..001d315
--- /dev/null
+++ b/reflash-bootloader/reflash-bootloader.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+
+#define error(s, a...) \
+ { \
+ printf("error: " s "\n", ##a); \
+ exit(-1); \
+ }
+
+#define error_errno(s, a...) error(s ": %s", ##a, strerror(errno))
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+enum omap_type_enum {
+ OMAP4460_EMU = 0,
+ OMAP4460_HS,
+ OMAP4460_HS_PROD,
+ OMAP4430_HS,
+};
+
+struct omap_type {
+ const char *family;
+ const char *type;
+ unsigned long msv_val;
+ const char *msv_type;
+ off_t offset;
+} omap_type_list[] = {
+ [OMAP4460_EMU] = {"OMAP4460", "EMU", 0x00000000, "eng", 0x1000},
+ [OMAP4460_HS] = {"OMAP4460", "HS", 0x00000000, "eng", 0x21000},
+ [OMAP4460_HS_PROD] = {"OMAP4460", "HS", 0xf0000f00, "prod", 0x41000},
+ [OMAP4430_HS] = {"OMAP4430", "HS", 0x00000000, "eng", 0x61000},
+};
+
+#define IMG_PIT_OFFSET 0UL
+#define IMG_SBL_OFFSET 0x81000UL
+
+#define MMC_PIT_OFFSET 0x4400UL
+#define MMC_XLOADER_OFFSET 0x20000UL
+#define MMC_SBL_OFFSET 0x80000UL
+
+#define PIT_SIZE 0x1000UL
+#define XLOADER_SIZE 0x20000UL
+
+static void drop_caches(void)
+{
+ int fd;
+ int ret;
+ char buf[] = "3\n";
+
+ fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
+ if (fd < 0)
+ error_errno("failed to open /proc/sys/vm/drop_caches");
+
+ ret = write(fd, buf, sizeof(buf));
+ if (ret < 0)
+ error_errno("failed to write to /proc/sys/vm/drop_caches");
+}
+
+static void read_file(const char *filename, char *buf, size_t size)
+{
+ int fd;
+ ssize_t ret;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ error_errno("failed to open %s", filename);
+
+ ret = read(fd, buf, size - 1);
+ if (ret < 0)
+ error_errno("failed to read %s", filename);
+ buf[ret] = 0;
+ while (buf[ret - 1] == '\n')
+ buf[--ret] = 0;
+
+ close(fd);
+}
+
+static const struct omap_type *get_omap_type(void)
+{
+ int fd;
+ char family[10];
+ char type[5];
+ char msv[9];
+ unsigned long msv_val;
+ ssize_t ret;
+ unsigned int i;
+
+ read_file("/sys/board_properties/soc/type", type, sizeof(type));
+ read_file("/sys/board_properties/soc/family", family, sizeof(family));
+ read_file("/sys/board_properties/soc/msv", msv, sizeof(msv));
+
+ msv_val = strtoul(msv, NULL, 16);
+
+ for (i = 0; i < ARRAY_SIZE(omap_type_list); i++)
+ if ((strcmp(omap_type_list[i].family, family) == 0) &&
+ (strcmp(omap_type_list[i].type, type) == 0) &&
+ msv_val == omap_type_list[i].msv_val)
+ return &omap_type_list[i];
+
+ error("unknown omap type %s %s %s (0x%08lx)", family, type, msv, msv_val);
+}
+
+static void zero_data(int to_fd, off_t to_offset, ssize_t size)
+{
+ char buf[4096];
+ int ret;
+ unsigned int to_write;
+
+ memset(buf, 0, sizeof(buf));
+
+ ret = lseek(to_fd, to_offset, SEEK_SET);
+ if (ret < 0)
+ error_errno("failed to seek output file to %lx", to_offset);
+
+ while (size != 0) {
+ to_write = size;
+ if (to_write > sizeof(buf))
+ to_write = sizeof(buf);
+
+ ret = write(to_fd, buf, to_write);
+ if (ret < 0)
+ error_errno("failed to write to output file");
+ size -= ret;
+ }
+}
+
+static void verify_data(int to_fd, off_t to_offset,
+ int from_fd, off_t from_offset,
+ ssize_t size)
+{
+ char buf_to[4096];
+ char buf_from[4096];
+ int ret;
+ int to_read;
+ int c;
+ char *ptr;
+
+ ret = lseek(to_fd, to_offset, SEEK_SET);
+ if (ret < 0)
+ error_errno("failed to seek output file to %lx", to_offset);
+
+ ret = lseek(from_fd, from_offset, SEEK_SET);
+ if (ret < 0)
+ error_errno("failed to seek input file to %lx", from_offset);
+
+ while (size != 0) {
+ to_read = sizeof(buf_to);
+ if (size > 0 && to_read > size)
+ to_read = size;
+
+ ptr = buf_to;
+ c = to_read;
+ while (c > 0) {
+ ret = read(to_fd, ptr, c);
+ if (ret < 0)
+ error_errno("failed to read from output file");
+ if (ret == 0 && size < 0)
+ return;
+ if (ret == 0)
+ error_errno("eof while reading output file");
+ ptr += ret;
+ c -= ret;
+ }
+
+ ptr = buf_from;
+ c = to_read;
+ while (c > 0) {
+ ret = read(from_fd, ptr, c);
+ if (ret < 0)
+ error_errno("failed to read from input file");
+ if (ret == 0 && size < 0)
+ return;
+ if (ret == 0)
+ error_errno("eof while reading input file");
+ ptr += ret;
+ c -= ret;
+ }
+
+ if (memcmp(buf_from, buf_to, to_read) != 0)
+ error("mismatch while verifying written data");
+
+ size -= to_read;
+ }
+}
+
+static void copy_data(int to_fd, off_t to_offset,
+ int from_fd, off_t from_offset,
+ ssize_t size)
+{
+ char buf[4096];
+ int ret;
+ int to_write;
+ const char *ptr;
+
+ ret = lseek(to_fd, to_offset, SEEK_SET);
+ if (ret < 0)
+ error_errno("failed to seek output file to %lx", to_offset);
+
+ ret = lseek(from_fd, from_offset, SEEK_SET);
+ if (ret < 0)
+ error_errno("failed to seek input file to %lx", from_offset);
+
+ while (size != 0) {
+ ret = read(from_fd, buf, sizeof(buf));
+ if (ret < 0)
+ error_errno("failed to read from input file");
+ if (ret == 0 && size > 0)
+ error_errno("eof while reading input file");
+ if (ret == 0)
+ return;
+
+ to_write = ret;
+ ptr = buf;
+
+ if (size > 0)
+ size -= to_write;
+
+ while (to_write > 0) {
+ ret = write(to_fd, ptr, to_write);
+ if (ret < 0)
+ error_errno("failed to write to output file");
+ to_write -= ret;
+ ptr += ret;
+ }
+ }
+}
+
+static void init(void)
+{
+ int ret;
+
+ umask(0);
+
+ ret = mkdir("/dev", 0755);
+ if (ret && errno != EEXIST)
+ error_errno("failed to create /dev");
+
+ ret = mkdir("/proc", 0755);
+ if (ret && errno != EEXIST)
+ error_errno("failed to create /proc");
+
+ ret = mkdir("/sys", 0755);
+ if (ret && errno != EEXIST)
+ error_errno("failed to create /sys");
+
+ ret = mount("proc", "/proc", "proc", 0, NULL);
+ if (ret)
+ error_errno("failed to mount proc");
+
+ ret = mount("sysfs", "/sys", "sysfs", 0, NULL);
+ if (ret)
+ error_errno("failed to mount sys");
+
+ ret = mkdir("/dev/block", 0755);
+ if (ret && errno != EEXIST)
+ error_errno("failed to create /dev/block");
+
+ ret = mknod("/dev/block/mmcblk0", S_IFBLK | 0755, makedev(179, 0));
+ if (ret)
+ error_errno("failed to create mmcblk0");
+}
+
+int main(int argc, char **argv)
+{
+ int in_fd;
+ int out_fd;
+ const struct omap_type *type;
+
+ if (getpid() == 1)
+ init();
+
+ in_fd = open("bootloader.img", O_RDONLY);
+ if (in_fd < 0)
+ error_errno("failed to open bootloader.img");
+
+ out_fd = open("/dev/block/mmcblk0", O_RDWR);
+ if (out_fd < 0)
+ error_errno("failed to open mmcblk0");
+
+ type = get_omap_type();
+
+ printf("Found %s %s %s\n", type->family, type->type, type->msv_type);
+
+ printf("Zeroing to end of sbl\n");
+ zero_data(out_fd, 0, MMC_SBL_OFFSET);
+
+ /* Don't write the partition table, let the bootloader do it on next boot */
+#if 0
+ printf("Writing partition-table from %lx to %lx\n",
+ IMG_PIT_OFFSET, MMC_PIT_OFFSET);
+ copy_data(out_fd, MMC_PIT_OFFSET, in_fd, IMG_PIT_OFFSET, PIT_SIZE);
+#endif
+
+ printf("Writing xloader from %lx to %lx\n",
+ type->offset, MMC_XLOADER_OFFSET);
+ copy_data(out_fd, MMC_XLOADER_OFFSET, in_fd, type->offset, XLOADER_SIZE);
+
+ printf("Writing sbl from %lx to %lx\n",
+ IMG_SBL_OFFSET, MMC_SBL_OFFSET);
+ copy_data(out_fd, MMC_SBL_OFFSET, in_fd, IMG_SBL_OFFSET, -1);
+
+#if 0
+ printf("Verifying partition table\n");
+ verify_data(out_fd, MMC_PIT_OFFSET, in_fd, IMG_PIT_OFFSET, PIT_SIZE);
+#endif
+
+ printf("Verifying xloader\n");
+ verify_data(out_fd, MMC_XLOADER_OFFSET, in_fd, type->offset, XLOADER_SIZE);
+
+ printf("Verifying sbl\n");
+ verify_data(out_fd, MMC_SBL_OFFSET, in_fd, IMG_SBL_OFFSET, -1);
+
+ printf("Syncing\n");
+ sync();
+
+ printf("Dropping caches\n");
+ drop_caches();
+
+ printf("Verifying xloader.img\n");
+ verify_data(out_fd, MMC_XLOADER_OFFSET, in_fd, type->offset, XLOADER_SIZE);
+
+ printf("Verifying sbl.img\n");
+ verify_data(out_fd, MMC_SBL_OFFSET, in_fd, IMG_SBL_OFFSET, -1);
+
+ printf("Done\n");
+
+ if (getpid() == 1) {
+ __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, "bootloader");
+
+ while (1) { sleep(1); }
+ }
+
+ return 0;
+}